17 #ifndef dealii_matrix_free_h 18 #define dealii_matrix_free_h 121 "Type of Number and of VectorizedArrayType do not match.");
561 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
564 const DoFHandlerType & dof_handler,
566 const QuadratureType & quad,
573 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
575 reinit(
const DoFHandlerType & dof_handler,
577 const QuadratureType & quad,
587 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
590 const DoFHandlerType & dof_handler,
592 const IndexSet & locally_owned_dofs,
593 const QuadratureType & quad,
617 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
620 const std::vector<const DoFHandlerType *> & dof_handler,
622 const std::vector<QuadratureType> & quad,
629 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
631 reinit(
const std::vector<const DoFHandlerType *> & dof_handler,
633 const std::vector<QuadratureType> & quad,
643 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
646 const std::vector<const DoFHandlerType *> & dof_handler,
648 const std::vector<IndexSet> & locally_owned_set,
649 const std::vector<QuadratureType> &quad,
659 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
662 const std::vector<const DoFHandlerType *> & dof_handler,
664 const QuadratureType & quad,
671 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
673 reinit(
const std::vector<const DoFHandlerType *> & dof_handler,
675 const QuadratureType & quad,
825 template <
typename OutVector,
typename InVector>
831 const std::pair<unsigned int, unsigned int> &)> &cell_operation,
833 const InVector & src,
834 const bool zero_dst_vector =
false)
const;
882 template <
typename CLASS,
typename OutVector,
typename InVector>
888 const std::pair<unsigned int, unsigned int> &)
const,
889 const CLASS * owning_class,
892 const bool zero_dst_vector =
false)
const;
897 template <
typename CLASS,
typename OutVector,
typename InVector>
903 const std::pair<unsigned int, unsigned int> &),
904 CLASS * owning_class,
907 const bool zero_dst_vector =
false)
const;
993 template <
typename CLASS,
typename OutVector,
typename InVector>
999 const std::pair<unsigned int, unsigned int> &)
const,
1000 const CLASS * owning_class,
1002 const InVector &src,
1003 const std::function<
void(
const unsigned int,
const unsigned int)>
1004 &operation_before_loop,
1005 const std::function<
void(
const unsigned int,
const unsigned int)>
1006 & operation_after_loop,
1007 const unsigned int dof_handler_index_pre_post = 0)
const;
1012 template <
typename CLASS,
typename OutVector,
typename InVector>
1014 cell_loop(
void (CLASS::*cell_operation)(
1018 const std::pair<unsigned int, unsigned int> &),
1019 CLASS * owning_class,
1021 const InVector &src,
1022 const std::function<
void(
const unsigned int,
const unsigned int)>
1023 &operation_before_loop,
1024 const std::function<
void(
const unsigned int,
const unsigned int)>
1025 & operation_after_loop,
1026 const unsigned int dof_handler_index_pre_post = 0)
const;
1032 template <
typename OutVector,
typename InVector>
1038 const std::pair<unsigned int, unsigned int> &)> &cell_operation,
1040 const InVector & src,
1041 const std::function<
void(
const unsigned int,
const unsigned int)>
1042 &operation_before_loop,
1043 const std::function<
void(
const unsigned int,
const unsigned int)>
1044 & operation_after_loop,
1045 const unsigned int dof_handler_index_pre_post = 0)
const;
1122 template <
typename OutVector,
typename InVector>
1124 loop(
const std::function<
1128 const std::pair<unsigned int, unsigned int> &)> &cell_operation,
1129 const std::function<
1133 const std::pair<unsigned int, unsigned int> &)> &face_operation,
1134 const std::function<
void(
1138 const std::pair<unsigned int, unsigned int> &)> &boundary_operation,
1140 const InVector & src,
1141 const bool zero_dst_vector =
false,
1232 template <
typename CLASS,
typename OutVector,
typename InVector>
1235 void (CLASS::*cell_operation)(
const MatrixFree &,
1238 const std::pair<unsigned int, unsigned int> &)
1240 void (CLASS::*face_operation)(
const MatrixFree &,
1243 const std::pair<unsigned int, unsigned int> &)
1245 void (CLASS::*boundary_operation)(
1249 const std::pair<unsigned int, unsigned int> &)
const,
1250 const CLASS * owning_class,
1252 const InVector & src,
1253 const bool zero_dst_vector =
false,
1262 template <
typename CLASS,
typename OutVector,
typename InVector>
1264 loop(
void (CLASS::*cell_operation)(
1268 const std::pair<unsigned int, unsigned int> &),
1269 void (CLASS::*face_operation)(
1273 const std::pair<unsigned int, unsigned int> &),
1274 void (CLASS::*boundary_operation)(
1278 const std::pair<unsigned int, unsigned int> &),
1279 CLASS * owning_class,
1281 const InVector & src,
1282 const bool zero_dst_vector =
false,
1352 template <
typename CLASS,
typename OutVector,
typename InVector>
1358 const std::pair<unsigned int, unsigned int> &)
const,
1359 const CLASS * owning_class,
1361 const InVector & src,
1362 const bool zero_dst_vector =
false,
1369 template <
typename CLASS,
typename OutVector,
typename InVector>
1375 const std::pair<unsigned int, unsigned int> &),
1376 CLASS * owning_class,
1378 const InVector & src,
1379 const bool zero_dst_vector =
false,
1386 template <
typename OutVector,
typename InVector>
1392 const std::pair<unsigned int, unsigned int> &)>
1395 const InVector & src,
1396 const bool zero_dst_vector =
false,
1407 std::pair<unsigned int, unsigned int>
1409 const unsigned int fe_degree,
1410 const unsigned int dof_handler_index = 0)
const;
1418 std::pair<unsigned int, unsigned int>
1420 const std::pair<unsigned int, unsigned int> &range,
1421 const unsigned int fe_index,
1422 const unsigned int dof_handler_index = 0)
const;
1450 template <
typename VectorType>
1453 const unsigned int dof_handler_index = 0)
const;
1475 template <
typename Number2>
1478 const unsigned int dof_handler_index = 0)
const;
1490 const std::shared_ptr<const Utilities::MPI::Partitioner> &
1503 get_ghost_set(
const unsigned int dof_handler_index = 0)
const;
1514 const std::vector<unsigned int> &
1528 renumber_dofs(std::vector<types::global_dof_index> &renumbering,
1529 const unsigned int dof_handler_index = 0);
1540 template <
int spacedim>
1641 std::array<types::boundary_id, VectorizedArrayType::size()>
1643 const unsigned int face_number)
const;
1653 template <
typename DoFHandlerType = DoFHandler<dim>>
1654 const DoFHandlerType &
1669 const unsigned int vector_number,
1670 const unsigned int dof_handler_index = 0)
const;
1679 const unsigned int vector_number)
const;
1693 std::pair<typename DoFHandler<dim>::cell_iterator,
unsigned int>
1695 const unsigned int vector_number,
1696 const bool interior =
true,
1697 const unsigned int fe_component = 0)
const;
1712 const unsigned int vector_number,
1713 const unsigned int dof_handler_index = 0)
const;
1768 const unsigned int hp_active_fe_index = 0)
const;
1775 const unsigned int hp_active_fe_index = 0)
const;
1783 const unsigned int hp_active_fe_index = 0)
const;
1791 const unsigned int hp_active_fe_index = 0)
const;
1798 const unsigned int hp_active_fe_index = 0)
const;
1805 const unsigned int hp_active_fe_index = 0)
const;
1820 std::pair<unsigned int, unsigned int>
1854 template <
typename StreamType>
1863 print(std::ostream &out)
const;
1882 const internal::MatrixFreeFunctions::
1883 MappingInfo<dim, Number, VectorizedArrayType> &
1890 get_dof_info(
const unsigned int dof_handler_index_component = 0)
const;
1917 get_shape_info(
const unsigned int dof_handler_index_component = 0,
1918 const unsigned int quad_index = 0,
1919 const unsigned int fe_base_element = 0,
1920 const unsigned int hp_active_fe_index = 0,
1921 const unsigned int hp_active_quad_index = 0)
const;
1927 VectorizedArrayType::size()> &
1987 template <
typename number2,
template <
int,
int>
class DoFHandlerType>
1991 const std::vector<
const DoFHandlerType<dim, dim> *> & dof_handler,
1993 const std::vector<IndexSet> & locally_owned_set,
2003 template <
typename number2>
2007 const std::vector<IndexSet> & locally_owned_set,
2041 : active_dof_handler(usual)
2057 } active_dof_handler;
2070 std::vector<internal::MatrixFreeFunctions::DoFInfo>
dof_info;
2148 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>>
2155 mutable std::list<std::pair<bool, AlignedVector<Number>>>
2172 template <
int dim,
typename Number,
typename VectorizedArrayType>
2173 template <
typename VectorType>
2177 const unsigned int comp)
const 2180 vec.reinit(
dof_info[comp].vector_partitioner->size());
2185 template <
int dim,
typename Number,
typename VectorizedArrayType>
2186 template <
typename Number2>
2190 const unsigned int comp)
const 2198 template <
int dim,
typename Number,
typename VectorizedArrayType>
2199 inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
2201 const unsigned int comp)
const 2204 return dof_info[comp].vector_partitioner;
2209 template <
int dim,
typename Number,
typename VectorizedArrayType>
2210 inline const std::vector<unsigned int> &
2212 const unsigned int comp)
const 2215 return dof_info[comp].constrained_dofs;
2220 template <
int dim,
typename Number,
typename VectorizedArrayType>
2230 template <
int dim,
typename Number,
typename VectorizedArrayType>
2233 const unsigned int dof_no)
const 2242 template <
int dim,
typename Number,
typename VectorizedArrayType>
2251 template <
int dim,
typename Number,
typename VectorizedArrayType>
2260 template <
int dim,
typename Number,
typename VectorizedArrayType>
2269 template <
int dim,
typename Number,
typename VectorizedArrayType>
2278 template <
int dim,
typename Number,
typename VectorizedArrayType>
2288 template <
int dim,
typename Number,
typename VectorizedArrayType>
2299 template <
int dim,
typename Number,
typename VectorizedArrayType>
2311 template <
int dim,
typename Number,
typename VectorizedArrayType>
2322 template <
int dim,
typename Number,
typename VectorizedArrayType>
2325 const unsigned int macro_face)
const 2337 template <
int dim,
typename Number,
typename VectorizedArrayType>
2338 inline std::array<types::boundary_id, VectorizedArrayType::size()>
2340 const unsigned int macro_cell,
2341 const unsigned int face_number)
const 2347 std::array<types::boundary_id, VectorizedArrayType::size()> result;
2356 template <
int dim,
typename Number,
typename VectorizedArrayType>
2357 inline const internal::MatrixFreeFunctions::
2358 MappingInfo<dim, Number, VectorizedArrayType> &
2366 template <
int dim,
typename Number,
typename VectorizedArrayType>
2369 const unsigned int dof_index)
const 2377 template <
int dim,
typename Number,
typename VectorizedArrayType>
2386 template <
int dim,
typename Number,
typename VectorizedArrayType>
2387 inline const Number *
2389 const unsigned int row)
const 2399 template <
int dim,
typename Number,
typename VectorizedArrayType>
2400 inline const Number *
2402 const unsigned int row)
const 2412 template <
int dim,
typename Number,
typename VectorizedArrayType>
2413 inline std::pair<unsigned int, unsigned int>
2415 const std::pair<unsigned int, unsigned int> &range,
2416 const unsigned int degree,
2417 const unsigned int dof_handler_component)
const 2419 if (
dof_info[dof_handler_component].cell_active_fe_index.empty())
2422 dof_info[dof_handler_component].fe_index_conversion.size(), 1);
2424 dof_info[dof_handler_component].fe_index_conversion[0].size(), 1);
2425 if (
dof_info[dof_handler_component].fe_index_conversion[0][0] == degree)
2428 return {range.second, range.second};
2431 const unsigned int fe_index =
2432 dof_info[dof_handler_component].fe_index_from_degree(0, degree);
2433 if (fe_index >=
dof_info[dof_handler_component].max_fe_index)
2434 return {range.second, range.second};
2438 dof_handler_component);
2443 template <
int dim,
typename Number,
typename VectorizedArrayType>
2446 const unsigned int macro_cell)
const 2449 return VectorizedArrayType::size() > 1 &&
2451 cell_level_index[(macro_cell + 1) * VectorizedArrayType::size() - 2];
2456 template <
int dim,
typename Number,
typename VectorizedArrayType>
2459 const unsigned int cell_batch_number)
const 2466 template <
int dim,
typename Number,
typename VectorizedArrayType>
2469 const unsigned int cell_batch_number)
const 2472 unsigned int n_lanes = VectorizedArrayType::size();
2473 while (n_lanes > 1 &&
2485 template <
int dim,
typename Number,
typename VectorizedArrayType>
2488 const unsigned int face_batch_number)
const 2491 unsigned int n_lanes = VectorizedArrayType::size();
2492 while (n_lanes > 1 &&
2493 face_info.
faces[face_batch_number].cells_interior[n_lanes - 1] ==
2502 template <
int dim,
typename Number,
typename VectorizedArrayType>
2505 const unsigned int dof_handler_index,
2506 const unsigned int active_fe_index)
const 2508 return dof_info[dof_handler_index].dofs_per_cell[active_fe_index];
2513 template <
int dim,
typename Number,
typename VectorizedArrayType>
2516 const unsigned int quad_index,
2517 const unsigned int active_fe_index)
const 2521 .descriptor[active_fe_index]
2527 template <
int dim,
typename Number,
typename VectorizedArrayType>
2530 const unsigned int dof_handler_index,
2531 const unsigned int active_fe_index)
const 2533 return dof_info[dof_handler_index].dofs_per_face[active_fe_index];
2538 template <
int dim,
typename Number,
typename VectorizedArrayType>
2541 const unsigned int quad_index,
2542 const unsigned int active_fe_index)
const 2546 .descriptor[active_fe_index]
2552 template <
int dim,
typename Number,
typename VectorizedArrayType>
2555 const unsigned int dof_handler_index)
const 2557 return dof_info[dof_handler_index].vector_partitioner->locally_owned_range();
2562 template <
int dim,
typename Number,
typename VectorizedArrayType>
2565 const unsigned int dof_handler_index)
const 2567 return dof_info[dof_handler_index].vector_partitioner->ghost_indices();
2572 template <
int dim,
typename Number,
typename VectorizedArrayType>
2575 const unsigned int dof_handler_index,
2576 const unsigned int index_quad,
2577 const unsigned int index_fe,
2578 const unsigned int active_fe_index,
2579 const unsigned int active_quad_index)
const 2582 const unsigned int ind =
2583 dof_info[dof_handler_index].global_base_element_offset + index_fe;
2588 return shape_info(ind, index_quad, active_fe_index, active_quad_index);
2593 template <
int dim,
typename Number,
typename VectorizedArrayType>
2595 VectorizedArrayType::size()> &
2597 const unsigned int macro_face)
const 2605 template <
int dim,
typename Number,
typename VectorizedArrayType>
2615 template <
int dim,
typename Number,
typename VectorizedArrayType>
2618 const unsigned int quad_index,
2619 const unsigned int active_fe_index)
const 2623 .descriptor[active_fe_index]
2629 template <
int dim,
typename Number,
typename VectorizedArrayType>
2632 const unsigned int quad_index,
2633 const unsigned int active_fe_index)
const 2637 .descriptor[active_fe_index]
2643 template <
int dim,
typename Number,
typename VectorizedArrayType>
2646 const unsigned int macro_cell)
const 2650 if (
dof_info[0].cell_active_fe_index.empty())
2653 return dof_info[0].cell_active_fe_index[macro_cell];
2658 template <
int dim,
typename Number,
typename VectorizedArrayType>
2659 inline std::pair<unsigned int, unsigned int>
2661 const unsigned int macro_face)
const 2664 if (
dof_info[0].cell_active_fe_index.empty())
2665 return std::make_pair(0
U, 0
U);
2667 std::pair<unsigned int, unsigned int> result;
2668 for (
unsigned int v = 0; v < VectorizedArrayType::size() &&
2675 .cell_active_fe_index[
face_info.
faces[macro_face].cells_interior[v]]);
2678 for (
unsigned int v = 0; v < VectorizedArrayType::size() &&
2685 .cell_active_fe_index[
face_info.
faces[macro_face].cells_exterior[v]]);
2693 template <
int dim,
typename Number,
typename VectorizedArrayType>
2702 template <
int dim,
typename Number,
typename VectorizedArrayType>
2710 template <
int dim,
typename Number,
typename VectorizedArrayType>
2719 template <
int dim,
typename Number,
typename VectorizedArrayType>
2724 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>;
2726 for (
typename list_type::iterator it = data.begin(); it != data.end(); ++it)
2727 if (it->first ==
false)
2733 return &data.front().second;
2738 template <
int dim,
typename Number,
typename VectorizedArrayType>
2744 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>;
2746 for (
typename list_type::iterator it = data.begin(); it != data.end(); ++it)
2747 if (&it->second == scratch)
2758 template <
int dim,
typename Number,
typename VectorizedArrayType>
2767 if (it->first ==
false)
2779 template <
int dim,
typename Number,
typename VectorizedArrayType>
2789 if (&it->second == scratch)
2804 namespace MatrixFreeImplementation
2806 template <
typename DoFHandlerType>
2807 inline std::vector<IndexSet>
2808 extract_locally_owned_index_sets(
2809 const std::vector<const DoFHandlerType *> &dofh,
2810 const unsigned int level)
2812 std::vector<IndexSet> locally_owned_set;
2813 locally_owned_set.reserve(dofh.size());
2814 for (
unsigned int j = 0; j < dofh.size(); j++)
2816 locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
2819 return locally_owned_set;
2822 template <
int dim,
int spacedim>
2823 inline std::vector<IndexSet>
2824 extract_locally_owned_index_sets(
2825 const std::vector<const ::DoFHandler<dim, spacedim> *> &dofh,
2826 const unsigned int level)
2828 std::vector<IndexSet> locally_owned_set;
2829 locally_owned_set.reserve(dofh.size());
2830 for (
unsigned int j = 0; j < dofh.size(); j++)
2832 locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
2834 locally_owned_set.push_back(dofh[j]->locally_owned_mg_dofs(level));
2835 return locally_owned_set;
2842 template <
int dim,
typename Number,
typename VectorizedArrayType>
2843 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2846 const DoFHandlerType & dof_handler,
2848 const QuadratureType & quad,
2853 std::vector<const AffineConstraints<number2> *> constraints;
2854 std::vector<QuadratureType> quads;
2856 dof_handlers.push_back(&dof_handler);
2857 constraints.push_back(&constraints_in);
2858 quads.push_back(quad);
2860 std::vector<IndexSet> locally_owned_sets =
2861 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2862 dof_handlers, additional_data.
mg_level);
2864 std::vector<hp::QCollection<1>> quad_hp;
2865 quad_hp.emplace_back(quad);
2877 template <
int dim,
typename Number,
typename VectorizedArrayType>
2878 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2882 const DoFHandlerType & dof_handler,
2884 const QuadratureType & quad,
2889 std::vector<const AffineConstraints<number2> *> constraints;
2891 dof_handlers.push_back(&dof_handler);
2892 constraints.push_back(&constraints_in);
2894 std::vector<IndexSet> locally_owned_sets =
2895 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2896 dof_handlers, additional_data.
mg_level);
2898 std::vector<hp::QCollection<1>> quad_hp;
2899 quad_hp.emplace_back(quad);
2911 template <
int dim,
typename Number,
typename VectorizedArrayType>
2912 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2915 const std::vector<const DoFHandlerType *> & dof_handler,
2917 const std::vector<QuadratureType> & quad,
2921 std::vector<IndexSet> locally_owned_set =
2922 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2923 dof_handler, additional_data.
mg_level);
2924 std::vector<hp::QCollection<1>> quad_hp;
2925 for (
unsigned int q = 0; q < quad.size(); ++q)
2926 quad_hp.emplace_back(quad[q]);
2937 template <
int dim,
typename Number,
typename VectorizedArrayType>
2938 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2941 const std::vector<const DoFHandlerType *> & dof_handler,
2943 const QuadratureType & quad,
2947 std::vector<IndexSet> locally_owned_set =
2948 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2949 dof_handler, additional_data.
mg_level);
2950 std::vector<hp::QCollection<1>> quad_hp;
2951 quad_hp.emplace_back(quad);
2962 template <
int dim,
typename Number,
typename VectorizedArrayType>
2963 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2967 const std::vector<const DoFHandlerType *> & dof_handler,
2969 const QuadratureType & quad,
2973 std::vector<IndexSet> locally_owned_set =
2974 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
2975 dof_handler, additional_data.
mg_level);
2976 std::vector<hp::QCollection<1>> quad_hp;
2977 quad_hp.emplace_back(quad);
2988 template <
int dim,
typename Number,
typename VectorizedArrayType>
2989 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
2993 const std::vector<const DoFHandlerType *> & dof_handler,
2995 const std::vector<QuadratureType> & quad,
2999 std::vector<IndexSet> locally_owned_set =
3000 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3001 dof_handler, additional_data.
mg_level);
3002 std::vector<hp::QCollection<1>> quad_hp;
3003 for (
unsigned int q = 0; q < quad.size(); ++q)
3004 quad_hp.emplace_back(quad[q]);
3015 template <
int dim,
typename Number,
typename VectorizedArrayType>
3016 template <
typename DoFHandlerType,
typename QuadratureType,
typename number2>
3020 const std::vector<const DoFHandlerType *> & dof_handler,
3022 const std::vector<IndexSet> & locally_owned_set,
3023 const std::vector<QuadratureType> & quad,
3028 std::vector<hp::QCollection<1>> quad_hp;
3029 for (
unsigned int q = 0; q < quad.size(); ++q)
3030 quad_hp.emplace_back(quad[q]);
3056 template <
int dim,
typename Number,
typename VectorizedArrayType>
3057 struct VectorDataExchange
3064 static constexpr
unsigned int channel_shift = 20;
3073 const ::MatrixFree<dim, Number, VectorizedArrayType> &matrix_free,
3074 const typename ::MatrixFree<dim, Number, VectorizedArrayType>::
3077 : matrix_free(matrix_free)
3078 , vector_face_access(
3079 matrix_free.get_task_info().face_partition_data.empty() ?
3081 DataAccessOnFaces::unspecified :
3083 , ghosts_were_set(
false)
3084 # ifdef DEAL_II_WITH_MPI 3085 , tmp_data(n_components)
3086 , requests(n_components)
3090 if (this->vector_face_access !=
3093 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
3095 matrix_free.get_dof_info(c).vector_partitioner_face_variants.size(),
3104 ~VectorDataExchange()
3106 # ifdef DEAL_II_WITH_MPI 3107 for (
unsigned int i = 0; i < tmp_data.size(); ++i)
3108 if (tmp_data[i] !=
nullptr)
3109 matrix_free.release_scratch_data_non_threadsafe(tmp_data[i]);
3119 template <
typename VectorType>
3122 const bool check_global_compatibility =
true)
const 3125 (void)check_global_compatibility;
3126 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
3129 check_global_compatibility ?
3130 vec.get_partitioner()->is_globally_compatible(
3131 *matrix_free.get_dof_info(c).vector_partitioner) :
3133 vec.get_partitioner()->is_compatible(
3134 *matrix_free.get_dof_info(c).vector_partitioner))
3139 return mf_component;
3149 get_partitioner(
const unsigned int mf_component)
const 3152 .vector_partitioner_face_variants.size(),
3154 if (vector_face_access ==
3157 return *matrix_free.get_dof_info(mf_component)
3158 .vector_partitioner_face_variants[0];
3159 else if (vector_face_access ==
3162 return *matrix_free.get_dof_info(mf_component)
3163 .vector_partitioner_face_variants[1];
3164 else if (vector_face_access ==
3167 return *matrix_free.get_dof_info(mf_component)
3168 .vector_partitioner_face_variants[2];
3169 else if (vector_face_access ==
3172 return *matrix_free.get_dof_info(mf_component)
3173 .vector_partitioner_face_variants[3];
3177 return *matrix_free.get_dof_info(mf_component)
3178 .vector_partitioner_face_variants[4];
3190 update_ghost_values_start(
const unsigned int ,
3200 typename std::enable_if<
3205 update_ghost_values_start(
const unsigned int component_in_block_vector,
3208 (void)component_in_block_vector;
3209 bool ghosts_set = vec.has_ghost_elements();
3211 ghosts_were_set =
true;
3213 vec.update_ghost_values();
3224 typename std::enable_if<
3229 update_ghost_values_start(
const unsigned int component_in_block_vector,
3232 (void)component_in_block_vector;
3233 bool ghosts_set = vec.has_ghost_elements();
3235 ghosts_were_set =
true;
3237 vec.update_ghost_values_start(component_in_block_vector + channel_shift);
3249 typename std::enable_if<
3254 update_ghost_values_start(
const unsigned int component_in_block_vector,
3259 "Type mismatch between VectorType and VectorDataExchange");
3260 (void)component_in_block_vector;
3261 bool ghosts_set = vec.has_ghost_elements();
3263 ghosts_were_set =
true;
3264 if (vector_face_access ==
3268 vec.update_ghost_values_start(component_in_block_vector +
3272 # ifdef DEAL_II_WITH_MPI 3273 const unsigned int mf_component = find_vector_in_mf(vec);
3274 if (&get_partitioner(mf_component) ==
3275 matrix_free.get_dof_info(mf_component).vector_partitioner.get())
3277 vec.update_ghost_values_start(component_in_block_vector +
3283 get_partitioner(mf_component);
3287 tmp_data[component_in_block_vector] =
3288 matrix_free.acquire_scratch_data_non_threadsafe();
3289 tmp_data[component_in_block_vector]->resize_fast(
3294 component_in_block_vector + channel_shift,
3299 vec.get_partitioner()->local_size(),
3300 vec.get_partitioner()->n_ghost_indices()),
3301 this->requests[component_in_block_vector]);
3317 update_ghost_values_finish(
const unsigned int ,
3329 typename std::enable_if<
3331 !has_exchange_on_subset<VectorType>::value,
3334 update_ghost_values_finish(
const unsigned int component_in_block_vector,
3337 (void)component_in_block_vector;
3338 vec.update_ghost_values_finish();
3350 typename std::enable_if<
3352 has_exchange_on_subset<VectorType>::value,
3355 update_ghost_values_finish(
const unsigned int component_in_block_vector,
3360 "Type mismatch between VectorType and VectorDataExchange");
3361 (void)component_in_block_vector;
3362 if (vector_face_access ==
3366 vec.update_ghost_values_finish();
3369 # ifdef DEAL_II_WITH_MPI 3374 const unsigned int mf_component = find_vector_in_mf(vec);
3376 get_partitioner(mf_component);
3378 matrix_free.get_dof_info(mf_component).vector_partitioner.get())
3380 vec.update_ghost_values_finish();
3389 vec.get_partitioner()->local_size(),
3390 vec.get_partitioner()->n_ghost_indices()),
3391 this->requests[component_in_block_vector]);
3393 matrix_free.release_scratch_data_non_threadsafe(
3394 tmp_data[component_in_block_vector]);
3395 tmp_data[component_in_block_vector] =
nullptr;
3399 vec.set_ghost_state(
true);
3410 typename std::enable_if<is_serial_or_dummy<VectorType>::value,
3413 compress_start(
const unsigned int ,
3428 compress_start(
const unsigned int component_in_block_vector,
3431 (void)component_in_block_vector;
3446 !has_exchange_on_subset<VectorType>::value,
3449 compress_start(
const unsigned int component_in_block_vector,
3452 (void)component_in_block_vector;
3454 vec.compress_start(component_in_block_vector + channel_shift);
3468 has_exchange_on_subset<VectorType>::value,
3471 compress_start(
const unsigned int component_in_block_vector,
3476 "Type mismatch between VectorType and VectorDataExchange");
3477 (void)component_in_block_vector;
3479 if (vector_face_access ==
3483 vec.compress_start(component_in_block_vector + channel_shift);
3486 # ifdef DEAL_II_WITH_MPI 3488 const unsigned int mf_component = find_vector_in_mf(vec);
3490 get_partitioner(mf_component);
3492 matrix_free.get_dof_info(mf_component).vector_partitioner.get())
3494 vec.compress_start(component_in_block_vector + channel_shift);
3501 tmp_data[component_in_block_vector] =
3502 matrix_free.acquire_scratch_data_non_threadsafe();
3503 tmp_data[component_in_block_vector]->resize_fast(
3509 component_in_block_vector + channel_shift,
3511 vec.get_partitioner()->n_ghost_indices()),
3514 this->requests[component_in_block_vector]);
3529 compress_finish(
const unsigned int ,
3543 !has_exchange_on_subset<VectorType>::value,
3546 compress_finish(
const unsigned int component_in_block_vector,
3549 (void)component_in_block_vector;
3564 has_exchange_on_subset<VectorType>::value,
3567 compress_finish(
const unsigned int component_in_block_vector,
3572 "Type mismatch between VectorType and VectorDataExchange");
3573 (void)component_in_block_vector;
3574 if (vector_face_access ==
3581 # ifdef DEAL_II_WITH_MPI 3585 const unsigned int mf_component = find_vector_in_mf(vec);
3588 get_partitioner(mf_component);
3590 matrix_free.get_dof_info(mf_component).vector_partitioner.get())
3602 tmp_data[component_in_block_vector]->
begin(),
3606 vec.get_partitioner()->n_ghost_indices()),
3607 this->requests[component_in_block_vector]);
3609 matrix_free.release_scratch_data_non_threadsafe(
3610 tmp_data[component_in_block_vector]);
3611 tmp_data[component_in_block_vector] =
nullptr;
3622 typename std::enable_if<is_serial_or_dummy<VectorType>::value,
3625 reset_ghost_values(
const VectorType & )
const 3640 reset_ghost_values(
const VectorType &vec)
const 3642 if (ghosts_were_set ==
true)
3645 vec.zero_out_ghosts();
3659 reset_ghost_values(
const VectorType &vec)
const 3663 "Type mismatch between VectorType and VectorDataExchange");
3664 if (ghosts_were_set ==
true)
3667 if (vector_face_access ==
3671 vec.zero_out_ghosts();
3674 # ifdef DEAL_II_WITH_MPI 3677 const unsigned int mf_component = find_vector_in_mf(vec);
3679 get_partitioner(mf_component);
3681 matrix_free.get_dof_info(mf_component).vector_partitioner.get())
3682 vec.zero_out_ghosts();
3685 for (std::vector<std::pair<unsigned int, unsigned int>>::
3686 const_iterator my_ghosts =
3691 for (
unsigned int j = my_ghosts->first; j < my_ghosts->
second;
3701 vec.set_ghost_state(
false);
3714 typename std::enable_if<has_exchange_on_subset<VectorType>::value,
3717 zero_vector_region(
const unsigned int range_index,
VectorType &vec)
const 3721 "Type mismatch between VectorType and VectorDataExchange");
3726 const unsigned int mf_component = find_vector_in_mf(vec,
false);
3728 matrix_free.get_dof_info(mf_component);
3736 for (
unsigned int id =
3758 VectorType>::type * =
nullptr,
3759 typename VectorType::value_type * =
nullptr>
3761 zero_vector_region(
const unsigned int range_index, VectorType &vec)
const 3764 vec =
typename VectorType::value_type();
3778 zero_vector_region(
const unsigned int, ...)
const 3782 "which provide VectorType::value_type"));
3787 const ::MatrixFree<dim, Number, VectorizedArrayType> &matrix_free;
3788 const typename ::MatrixFree<dim, Number, VectorizedArrayType>::
3789 DataAccessOnFaces vector_face_access;
3790 bool ghosts_were_set;
3791 # ifdef DEAL_II_WITH_MPI 3792 std::vector<AlignedVector<Number> *> tmp_data;
3793 std::vector<std::vector<MPI_Request>> requests;
3797 template <
typename VectorStruct>
3801 template <
typename VectorStruct>
3803 n_components_block(
const VectorStruct &vec,
3804 std::integral_constant<bool, true>)
3806 unsigned int components = 0;
3807 for (
unsigned int bl = 0; bl < vec.n_blocks(); ++bl)
3812 template <
typename VectorStruct>
3814 n_components_block(
const VectorStruct &, std::integral_constant<bool, false>)
3819 template <
typename VectorStruct>
3823 return n_components_block(
3827 template <
typename VectorStruct>
3831 unsigned int components = 0;
3832 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3833 components += n_components_block(
3839 template <
typename VectorStruct>
3843 unsigned int components = 0;
3844 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3845 components += n_components_block(
3859 typename VectorStruct,
3861 VectorStruct>::type * =
nullptr>
3862 constexpr
unsigned int 3863 get_communication_block_size(
const VectorStruct &)
3871 typename VectorStruct,
3873 VectorStruct>::type * =
nullptr>
3874 constexpr
unsigned int 3875 get_communication_block_size(
const VectorStruct &)
3877 return VectorStruct::communication_block_size;
3892 typename VectorStruct,
3894 typename VectorizedArrayType,
3896 VectorStruct>::type * =
nullptr>
3898 update_ghost_values_start(
3899 const VectorStruct & vec,
3900 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
3901 const unsigned int channel = 0)
3903 if (get_communication_block_size(vec) < vec.n_blocks())
3907 exchanger.ghosts_were_set = vec.has_ghost_elements();
3908 vec.update_ghost_values();
3912 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
3913 update_ghost_values_start(vec.block(i), exchanger, channel + i);
3921 typename VectorStruct,
3923 typename VectorizedArrayType,
3925 VectorStruct>::type * =
nullptr>
3927 update_ghost_values_start(
3928 const VectorStruct & vec,
3929 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
3930 const unsigned int channel = 0)
3932 exchanger.update_ghost_values_start(channel, vec);
3939 typename VectorStruct,
3941 typename VectorizedArrayType>
3943 update_ghost_values_start(
3944 const std::vector<VectorStruct> & vec,
3945 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
3947 unsigned int component_index = 0;
3948 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3950 update_ghost_values_start(vec[comp], exchanger, component_index);
3959 typename VectorStruct,
3961 typename VectorizedArrayType>
3963 update_ghost_values_start(
3964 const std::vector<VectorStruct *> & vec,
3965 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
3967 unsigned int component_index = 0;
3968 for (
unsigned int comp = 0; comp < vec.size(); comp++)
3970 update_ghost_values_start(*vec[comp], exchanger, component_index);
3983 typename VectorStruct,
3985 typename VectorizedArrayType,
3986 typename std::enable_if<IsBlockVector<VectorStruct>::value,
3987 VectorStruct>::type * =
nullptr>
3989 update_ghost_values_finish(
3990 const VectorStruct & vec,
3991 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
3992 const unsigned int channel = 0)
3994 if (get_communication_block_size(vec) < vec.n_blocks())
4000 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4001 update_ghost_values_finish(vec.block(i), exchanger, channel + i);
4008 typename VectorStruct,
4010 typename VectorizedArrayType,
4011 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4012 VectorStruct>::type * =
nullptr>
4014 update_ghost_values_finish(
4015 const VectorStruct & vec,
4016 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4017 const unsigned int channel = 0)
4019 exchanger.update_ghost_values_finish(channel, vec);
4026 typename VectorStruct,
4028 typename VectorizedArrayType>
4030 update_ghost_values_finish(
4031 const std::vector<VectorStruct> & vec,
4032 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4034 unsigned int component_index = 0;
4035 for (
unsigned int comp = 0; comp < vec.size(); comp++)
4037 update_ghost_values_finish(vec[comp], exchanger, component_index);
4046 typename VectorStruct,
4048 typename VectorizedArrayType>
4050 update_ghost_values_finish(
4051 const std::vector<VectorStruct *> & vec,
4052 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4054 unsigned int component_index = 0;
4055 for (
unsigned int comp = 0; comp < vec.size(); comp++)
4057 update_ghost_values_finish(*vec[comp], exchanger, component_index);
4070 typename VectorStruct,
4072 typename VectorizedArrayType,
4073 typename std::enable_if<IsBlockVector<VectorStruct>::value,
4074 VectorStruct>::type * =
nullptr>
4078 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4079 const unsigned int channel = 0)
4081 if (get_communication_block_size(vec) < vec.n_blocks())
4084 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4085 compress_start(vec.block(i), exchanger, channel + i);
4092 typename VectorStruct,
4094 typename VectorizedArrayType,
4095 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4096 VectorStruct>::type * =
nullptr>
4100 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4101 const unsigned int channel = 0)
4103 exchanger.compress_start(channel, vec);
4110 typename VectorStruct,
4112 typename VectorizedArrayType>
4115 std::vector<VectorStruct> & vec,
4116 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4118 unsigned int component_index = 0;
4119 for (
unsigned int comp = 0; comp < vec.size(); comp++)
4121 compress_start(vec[comp], exchanger, component_index);
4130 typename VectorStruct,
4132 typename VectorizedArrayType>
4135 std::vector<VectorStruct *> & vec,
4136 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4138 unsigned int component_index = 0;
4139 for (
unsigned int comp = 0; comp < vec.size(); comp++)
4141 compress_start(*vec[comp], exchanger, component_index);
4154 typename VectorStruct,
4156 typename VectorizedArrayType,
4157 typename std::enable_if<IsBlockVector<VectorStruct>::value,
4158 VectorStruct>::type * =
nullptr>
4162 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4163 const unsigned int channel = 0)
4165 if (get_communication_block_size(vec) < vec.n_blocks())
4171 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4172 compress_finish(vec.block(i), exchanger, channel + i);
4179 typename VectorStruct,
4181 typename VectorizedArrayType,
4182 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4183 VectorStruct>::type * =
nullptr>
4187 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4188 const unsigned int channel = 0)
4190 exchanger.compress_finish(channel, vec);
4197 typename VectorStruct,
4199 typename VectorizedArrayType>
4202 std::vector<VectorStruct> & vec,
4203 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4205 unsigned int component_index = 0;
4206 for (
unsigned int comp = 0; comp < vec.size(); comp++)
4208 compress_finish(vec[comp], exchanger, component_index);
4217 typename VectorStruct,
4219 typename VectorizedArrayType>
4222 std::vector<VectorStruct *> & vec,
4223 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4225 unsigned int component_index = 0;
4226 for (
unsigned int comp = 0; comp < vec.size(); comp++)
4228 compress_finish(*vec[comp], exchanger, component_index);
4245 typename VectorStruct,
4247 typename VectorizedArrayType,
4248 typename std::enable_if<IsBlockVector<VectorStruct>::value,
4249 VectorStruct>::type * =
nullptr>
4252 const VectorStruct & vec,
4253 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4256 if (exchanger.ghosts_were_set ==
true)
4259 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4260 reset_ghost_values(vec.block(i), exchanger);
4267 typename VectorStruct,
4269 typename VectorizedArrayType,
4270 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4271 VectorStruct>::type * =
nullptr>
4274 const VectorStruct & vec,
4275 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4277 exchanger.reset_ghost_values(vec);
4284 typename VectorStruct,
4286 typename VectorizedArrayType>
4289 const std::vector<VectorStruct> & vec,
4290 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4293 if (exchanger.ghosts_were_set ==
true)
4296 for (
unsigned int comp = 0; comp < vec.size(); comp++)
4297 reset_ghost_values(vec[comp], exchanger);
4304 typename VectorStruct,
4306 typename VectorizedArrayType>
4309 const std::vector<VectorStruct *> & vec,
4310 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4313 if (exchanger.ghosts_were_set ==
true)
4316 for (
unsigned int comp = 0; comp < vec.size(); comp++)
4317 reset_ghost_values(*vec[comp], exchanger);
4328 typename VectorStruct,
4330 typename VectorizedArrayType,
4331 typename std::enable_if<IsBlockVector<VectorStruct>::value,
4332 VectorStruct>::type * =
nullptr>
4335 const unsigned int range_index,
4337 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4339 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4340 exchanger.zero_vector_region(range_index, vec.block(i));
4347 typename VectorStruct,
4349 typename VectorizedArrayType,
4350 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4351 VectorStruct>::type * =
nullptr>
4354 const unsigned int range_index,
4356 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4358 exchanger.zero_vector_region(range_index, vec);
4365 typename VectorStruct,
4367 typename VectorizedArrayType>
4370 const unsigned int range_index,
4371 std::vector<VectorStruct> & vec,
4372 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4374 for (
unsigned int comp = 0; comp < vec.size(); comp++)
4375 zero_vector_region(range_index, vec[comp], exchanger);
4382 typename VectorStruct,
4384 typename VectorizedArrayType>
4387 const unsigned int range_index,
4388 std::vector<VectorStruct *> & vec,
4389 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4391 for (
unsigned int comp = 0; comp < vec.size(); comp++)
4392 zero_vector_region(range_index, *vec[comp], exchanger);
4397 namespace MatrixFreeFunctions
4401 template <
typename,
typename,
typename,
typename,
bool>
4402 struct InterfaceSelector
4406 template <
typename MF,
4410 struct InterfaceSelector<MF, InVector, OutVector, Container, true>
4412 using function_type = void (Container::*)(
4416 const std::pair<unsigned int, unsigned int> &)
const;
4420 template <
typename MF,
4424 struct InterfaceSelector<MF, InVector, OutVector, Container, false>
4426 using function_type =
4427 void (Container::*)(
const MF &,
4430 const std::pair<unsigned int, unsigned int> &);
4438 template <
typename MF,
4443 class MFWorker :
public MFWorkerInterface
4447 using function_type =
typename MatrixFreeFunctions::
4448 InterfaceSelector<MF, InVector, OutVector, Container, is_constant>::
4452 MFWorker(
const MF & matrix_free,
4453 const InVector & src,
4455 const bool zero_dst_vector_setting,
4456 const Container & container,
4457 function_type cell_function,
4458 function_type face_function,
4459 function_type boundary_function,
4460 const typename MF::DataAccessOnFaces src_vector_face_access =
4462 const typename MF::DataAccessOnFaces dst_vector_face_access =
4464 const std::function<
void(
const unsigned int,
const unsigned int)>
4465 &operation_before_loop = {},
4466 const std::function<void(const unsigned int, const unsigned int)>
4467 & operation_after_loop = {},
4468 const unsigned int dof_handler_index_pre_post = 0)
4469 : matrix_free(matrix_free)
4470 , container(const_cast<Container &>(container))
4471 , cell_function(cell_function)
4472 , face_function(face_function)
4473 , boundary_function(boundary_function)
4476 , src_data_exchanger(matrix_free,
4477 src_vector_face_access,
4479 , dst_data_exchanger(matrix_free,
4480 dst_vector_face_access,
4483 , zero_dst_vector_setting(zero_dst_vector_setting &&
4484 !src_and_dst_are_same)
4485 , operation_before_loop(operation_before_loop)
4486 , operation_after_loop(operation_after_loop)
4487 , dof_handler_index_pre_post(dof_handler_index_pre_post)
4492 cell(
const std::pair<unsigned int, unsigned int> &cell_range)
override 4494 if (cell_function !=
nullptr && cell_range.second > cell_range.first)
4496 cell_function)(matrix_free, this->dst, this->src, cell_range);
4502 face(
const std::pair<unsigned int, unsigned int> &face_range)
override 4504 if (face_function !=
nullptr && face_range.second > face_range.first)
4506 face_function)(matrix_free, this->dst, this->src, face_range);
4512 boundary(
const std::pair<unsigned int, unsigned int> &face_range)
override 4514 if (boundary_function !=
nullptr && face_range.second > face_range.first)
4516 boundary_function)(matrix_free, this->dst, this->src, face_range);
4526 vector_update_ghosts_start()
override 4528 if (!src_and_dst_are_same)
4529 internal::update_ghost_values_start(src, src_data_exchanger);
4534 vector_update_ghosts_finish()
override 4536 if (!src_and_dst_are_same)
4537 internal::update_ghost_values_finish(src, src_data_exchanger);
4542 vector_compress_start()
override 4544 internal::compress_start(dst, dst_data_exchanger);
4549 vector_compress_finish()
override 4551 internal::compress_finish(dst, dst_data_exchanger);
4552 if (!src_and_dst_are_same)
4553 internal::reset_ghost_values(src, src_data_exchanger);
4558 zero_dst_vector_range(
const unsigned int range_index)
override 4560 if (zero_dst_vector_setting)
4561 internal::zero_vector_region(range_index, dst, dst_data_exchanger);
4565 cell_loop_pre_range(
const unsigned int range_index)
override 4567 if (operation_before_loop)
4570 matrix_free.get_dof_info(dof_handler_index_pre_post);
4577 operation_before_loop,
4584 for (
unsigned int id =
4595 cell_loop_post_range(
const unsigned int range_index)
override 4597 if (operation_after_loop)
4600 matrix_free.get_dof_info(dof_handler_index_pre_post);
4607 operation_after_loop,
4614 for (
unsigned int id =
4625 const MF & matrix_free;
4626 Container & container;
4627 function_type cell_function;
4628 function_type face_function;
4629 function_type boundary_function;
4631 const InVector &src;
4633 VectorDataExchange<MF::dimension,
4634 typename MF::value_type,
4635 typename MF::vectorized_value_type>
4637 VectorDataExchange<MF::dimension,
4638 typename MF::value_type,
4639 typename MF::vectorized_value_type>
4641 const bool src_and_dst_are_same;
4642 const bool zero_dst_vector_setting;
4643 const std::function<void(const unsigned int, const unsigned int)>
4644 operation_before_loop;
4645 const std::function<void(const unsigned int, const unsigned int)>
4646 operation_after_loop;
4647 const unsigned int dof_handler_index_pre_post;
4656 template <
class MF,
typename InVector,
typename OutVector>
4657 struct MFClassWrapper
4659 using function_type =
4660 std::function<void(
const MF &,
4663 const std::pair<unsigned int, unsigned int> &)>;
4665 MFClassWrapper(
const function_type cell,
4666 const function_type face,
4667 const function_type boundary)
4670 , boundary(boundary)
4674 cell_integrator(
const MF & mf,
4676 const InVector & src,
4677 const std::pair<unsigned int, unsigned int> &range)
const 4680 cell(mf, dst, src, range);
4684 face_integrator(
const MF & mf,
4686 const InVector & src,
4687 const std::pair<unsigned int, unsigned int> &range)
const 4690 face(mf, dst, src, range);
4694 boundary_integrator(
4697 const InVector & src,
4698 const std::pair<unsigned int, unsigned int> &range)
const 4701 boundary(mf, dst, src, range);
4704 const function_type cell;
4705 const function_type face;
4706 const function_type boundary;
4713 template <
int dim,
typename Number,
typename VectorizedArrayType>
4714 template <
typename OutVector,
typename InVector>
4720 const std::pair<unsigned int, unsigned int> &)>
4723 const InVector &src,
4724 const bool zero_dst_vector)
const 4727 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
4730 Wrapper wrap(cell_operation,
nullptr,
nullptr);
4731 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
4741 &Wrapper::cell_integrator,
4742 &Wrapper::face_integrator,
4743 &Wrapper::boundary_integrator);
4750 template <
int dim,
typename Number,
typename VectorizedArrayType>
4751 template <
typename OutVector,
typename InVector>
4757 const std::pair<unsigned int, unsigned int> &)>
4760 const InVector &src,
4761 const std::function<
void(
const unsigned int,
const unsigned int)>
4762 &operation_before_loop,
4763 const std::function<
void(
const unsigned int,
const unsigned int)>
4764 & operation_after_loop,
4765 const unsigned int dof_handler_index_pre_post)
const 4768 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
4771 Wrapper wrap(cell_operation,
nullptr,
nullptr);
4772 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
4782 &Wrapper::cell_integrator,
4783 &Wrapper::face_integrator,
4784 &Wrapper::boundary_integrator,
4787 operation_before_loop,
4788 operation_after_loop,
4789 dof_handler_index_pre_post);
4796 template <
int dim,
typename Number,
typename VectorizedArrayType>
4797 template <
typename OutVector,
typename InVector>
4803 const std::pair<unsigned int, unsigned int> &)>
4808 const std::pair<unsigned int, unsigned int> &)>
4813 const std::pair<unsigned int, unsigned int> &)>
4814 & boundary_operation,
4816 const InVector & src,
4817 const bool zero_dst_vector,
4822 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
4825 Wrapper wrap(cell_operation, face_operation, boundary_operation);
4826 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
4836 &Wrapper::cell_integrator,
4837 &Wrapper::face_integrator,
4838 &Wrapper::boundary_integrator,
4839 src_vector_face_access,
4840 dst_vector_face_access);
4847 template <
int dim,
typename Number,
typename VectorizedArrayType>
4848 template <
typename CLASS,
typename OutVector,
typename InVector>
4851 void (CLASS::*function_pointer)(
4855 const std::pair<unsigned int, unsigned int> &)
const,
4856 const CLASS * owning_class,
4858 const InVector &src,
4859 const bool zero_dst_vector)
const 4861 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
4879 template <
int dim,
typename Number,
typename VectorizedArrayType>
4880 template <
typename CLASS,
typename OutVector,
typename InVector>
4883 void (CLASS::*function_pointer)(
4887 const std::pair<unsigned int, unsigned int> &)
const,
4888 const CLASS * owning_class,
4890 const InVector &src,
4891 const std::function<
void(
const unsigned int,
const unsigned int)>
4892 &operation_before_loop,
4893 const std::function<
void(
const unsigned int,
const unsigned int)>
4894 & operation_after_loop,
4895 const unsigned int dof_handler_index_pre_post)
const 4897 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
4912 operation_before_loop,
4913 operation_after_loop,
4914 dof_handler_index_pre_post);
4920 template <
int dim,
typename Number,
typename VectorizedArrayType>
4921 template <
typename CLASS,
typename OutVector,
typename InVector>
4924 void (CLASS::*cell_operation)(
4928 const std::pair<unsigned int, unsigned int> &)
const,
4929 void (CLASS::*face_operation)(
4933 const std::pair<unsigned int, unsigned int> &)
const,
4934 void (CLASS::*boundary_operation)(
4938 const std::pair<unsigned int, unsigned int> &)
const,
4939 const CLASS * owning_class,
4941 const InVector & src,
4942 const bool zero_dst_vector,
4946 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
4959 src_vector_face_access,
4960 dst_vector_face_access);
4966 template <
int dim,
typename Number,
typename VectorizedArrayType>
4967 template <
typename CLASS,
typename OutVector,
typename InVector>
4970 void (CLASS::*function_pointer)(
4974 const std::pair<unsigned int, unsigned int> &),
4975 CLASS * owning_class,
4977 const InVector &src,
4978 const bool zero_dst_vector)
const 4980 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
4998 template <
int dim,
typename Number,
typename VectorizedArrayType>
4999 template <
typename CLASS,
typename OutVector,
typename InVector>
5002 void (CLASS::*function_pointer)(
5006 const std::pair<unsigned int, unsigned int> &),
5007 CLASS * owning_class,
5009 const InVector &src,
5010 const std::function<
void(
const unsigned int,
const unsigned int)>
5011 &operation_before_loop,
5012 const std::function<
void(
const unsigned int,
const unsigned int)>
5013 & operation_after_loop,
5014 const unsigned int dof_handler_index_pre_post)
const 5016 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5031 operation_before_loop,
5032 operation_after_loop,
5033 dof_handler_index_pre_post);
5039 template <
int dim,
typename Number,
typename VectorizedArrayType>
5040 template <
typename CLASS,
typename OutVector,
typename InVector>
5043 void (CLASS::*cell_operation)(
5047 const std::pair<unsigned int, unsigned int> &),
5048 void (CLASS::*face_operation)(
5052 const std::pair<unsigned int, unsigned int> &),
5053 void (CLASS::*boundary_operation)(
5057 const std::pair<unsigned int, unsigned int> &),
5058 CLASS * owning_class,
5060 const InVector & src,
5061 const bool zero_dst_vector,
5065 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5078 src_vector_face_access,
5079 dst_vector_face_access);
5085 template <
int dim,
typename Number,
typename VectorizedArrayType>
5086 template <
typename CLASS,
typename OutVector,
typename InVector>
5089 void (CLASS::*function_pointer)(
5093 const std::pair<unsigned int, unsigned int> &)
const,
5094 const CLASS * owning_class,
5096 const InVector & src,
5097 const bool zero_dst_vector,
5100 auto src_vector_face_access_temp = src_vector_face_access;
5106 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5119 src_vector_face_access_temp,
5126 template <
int dim,
typename Number,
typename VectorizedArrayType>
5127 template <
typename CLASS,
typename OutVector,
typename InVector>
5130 void (CLASS::*function_pointer)(
5134 const std::pair<unsigned int, unsigned int> &),
5135 CLASS * owning_class,
5137 const InVector & src,
5138 const bool zero_dst_vector,
5141 auto src_vector_face_access_temp = src_vector_face_access;
5147 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5160 src_vector_face_access_temp,
5167 template <
int dim,
typename Number,
typename VectorizedArrayType>
5168 template <
typename OutVector,
typename InVector>
5174 const std::pair<unsigned int, unsigned int> &)>
5177 const InVector & src,
5178 const bool zero_dst_vector,
5181 auto src_vector_face_access_temp = src_vector_face_access;
5188 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5191 Wrapper wrap(cell_operation,
nullptr,
nullptr);
5193 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5203 &Wrapper::cell_integrator,
5204 &Wrapper::face_integrator,
5205 &Wrapper::boundary_integrator,
5206 src_vector_face_access_temp,
5212 #endif // ifndef DOXYGEN Transformed quadrature weights.
Table< 4, internal::MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > > shape_info
void print_memory_consumption(StreamType &out) 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
static const unsigned int invalid_unsigned_int
unsigned int n_components_filled(const unsigned int cell_batch_number) const
std::vector< std::pair< unsigned int, unsigned int > > vector_zero_range_list
AlignedVector< Number > * acquire_scratch_data_non_threadsafe() const
#define AssertDimension(dim1, dim2)
~MatrixFree() override=default
unsigned int n_boundary_face_batches() const
A class that provides a separate storage location on each thread that accesses the object...
unsigned int local_size() 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
const Quadrature< dim - 1 > & get_face_quadrature(const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0) const
unsigned int get_dofs_per_cell(const unsigned int dof_handler_index=0, const unsigned int hp_active_fe_index=0) const
std::vector< unsigned int > cell_loop_pre_list_index
unsigned int get_cell_category(const unsigned int macro_cell) const
unsigned int get_mg_level() 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
unsigned int n_ghost_cell_batches() const
unsigned int n_components() const
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > & 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 get_n_q_points_face(const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0) const
void loop(MFWorkerInterface &worker) const
unsigned int n_inner_face_batches() const
bool mapping_is_initialized
#define AssertIndexRange(index, range)
AdditionalData(const AdditionalData &other)
std::shared_ptr< const Utilities::MPI::Partitioner > vector_partitioner
const internal::MatrixFreeFunctions::DoFInfo & get_dof_info(const unsigned int dof_handler_index_component=0) const
std::vector< unsigned int > vector_zero_range_list_index
std::list< std::pair< bool, AlignedVector< Number > > > scratch_pad_non_threadsafe
void make_connectivity_graph_faces(DynamicSparsityPattern &connectivity)
std::pair< unsigned int, unsigned int > get_face_category(const unsigned int macro_face) const
const DoFHandlerType & get_dof_handler(const unsigned int dof_handler_index=0) const
const std::vector< std::pair< unsigned int, unsigned int > > & ghost_indices_within_larger_ghost_set() const
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
bool mapping_initialized() const
void reinit(const size_type size, const bool omit_zeroing_entries=false)
UpdateFlags mapping_update_flags_boundary_faces
static ::ExceptionBase & ExcNotInitialized()
std::vector< unsigned int > cell_partition_data
#define AssertThrow(cond, exc)
std::vector< SmartPointer< const hp::DoFHandler< dim > > > hp_dof_handler
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
std::size_t memory_consumption() const
bool cell_vectorization_categories_strict
static ::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
const Number * constraint_pool_end(const unsigned int pool_index) const
void internal_reinit(const Mapping< dim > &mapping, const std::vector< const DoFHandlerType< dim, 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)
const IndexSet & get_ghost_set(const unsigned int dof_handler_index=0) const
::Table< 3, unsigned int > cell_and_face_to_plain_faces
unsigned int n_active_entries_per_cell_batch(const unsigned int cell_batch_number) const
static const unsigned int dimension
std::vector< unsigned int > cell_loop_post_list_index
typename ActiveSelector::active_cell_iterator active_cell_iterator
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 print(std::ostream &out) const
const Number * constraint_pool_begin(const unsigned int pool_index) const
DoFHandler< dim >::cell_iterator get_cell_iterator(const unsigned int macro_cell_number, const unsigned int vector_number, const unsigned int dof_handler_index=0) const
const Table< 3, unsigned int > & get_cell_and_face_to_plain_faces() const
static ::ExceptionBase & ExcMessage(std::string arg1)
bool indices_initialized() const
const internal::MatrixFreeFunctions::MappingInfo< dim, Number, VectorizedArrayType > & get_mapping_info() const
void loop(const std::function< void(const MatrixFree< dim, Number, VectorizedArrayType > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &cell_operation, const std::function< void(const MatrixFree< dim, Number, VectorizedArrayType > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &face_operation, const std::function< void(const MatrixFree< dim, Number, VectorizedArrayType > &, 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
const IndexSet & get_locally_owned_set(const unsigned int dof_handler_index=0) const
void initialize_dof_handlers(const std::vector< const DoFHandler< dim > *> &dof_handlers, const AdditionalData &additional_data)
void cell_loop(const std::function< void(const MatrixFree< dim, Number, VectorizedArrayType > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &cell_operation, OutVector &dst, const InVector &src, const bool zero_dst_vector=false) const
unsigned int n_base_elements(const unsigned int dof_handler_index) const
unsigned int n_ghost_indices() const
std::vector< std::pair< unsigned int, unsigned int > > cell_loop_pre_list
unsigned int n_ghost_inner_face_batches() const
#define Assert(cond, exc)
void apply_to_subranges(const tbb::blocked_range< RangeType > &range, const Function &f)
internal::MatrixFreeFunctions::FaceInfo< VectorizedArrayType::size()> face_info
const types::boundary_id invalid_boundary_id
std::vector< std::pair< unsigned int, unsigned int > > cell_level_index
UpdateFlags mapping_update_flags_inner_faces
std::vector< unsigned int > boundary_partition_data
std::vector< internal::MatrixFreeFunctions::DoFInfo > dof_info
#define DEAL_II_NAMESPACE_CLOSE
unsigned int get_dofs_per_face(const unsigned int dof_handler_index=0, const unsigned int hp_active_fe_index=0) const
UpdateFlags mapping_update_flags_faces_by_cells
unsigned int & level_mg_handler
unsigned int n_active_entries_per_face_batch(const unsigned int face_batch_number) const
AlignedVector< VectorizedArrayType > * acquire_scratch_data() const
unsigned int n_constraint_pool_entries() const
TasksParallelScheme tasks_parallel_scheme
std::vector< unsigned int > cell_vectorization_category
unsigned int n_cell_batches() const
unsigned int n_active_cells
const std::shared_ptr< const Utilities::MPI::Partitioner > & get_vector_partitioner(const unsigned int dof_handler_index=0) const
std::array< types::boundary_id, VectorizedArrayType::size()> get_faces_by_cells_boundary_id(const unsigned int macro_cell, const unsigned int face_number) const
std::vector< FaceToCellTopology< vectorization_width > > faces
std::vector< Number > constraint_pool_data
bool hold_all_faces_to_owned_cells
unsigned int n_dof_handlers
types::boundary_id get_boundary_id(const unsigned int macro_face) const
std::vector< unsigned int > face_partition_data
unsigned int n_macro_cells() const
::Table< 3, types::boundary_id > cell_and_face_boundary_id
const std::vector< unsigned int > & get_constrained_dofs(const unsigned int dof_handler_index=0) const
internal::MatrixFreeFunctions::TaskInfo task_info
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 mg_level=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)
size_type size(const unsigned int i) const
void update_mapping(const Mapping< dim > &mapping)
const internal::MatrixFreeFunctions::TaskInfo & get_task_info() const
void initialize_dof_vector(VectorType &vec, const unsigned int dof_handler_index=0) const
#define DEAL_II_NAMESPACE_OPEN
VectorType::value_type * begin(VectorType &V)
Shape function gradients.
bool indices_are_initialized
std::pair< int, int > get_cell_level_and_index(const unsigned int macro_cell_number, const unsigned int vector_number) const
void renumber_dofs(std::vector< types::global_dof_index > &renumbering, const unsigned int dof_handler_index=0)
std::pair< typename DoFHandler< dim >::cell_iterator, unsigned int > get_face_iterator(const unsigned int face_batch_number, const unsigned int vector_number, const bool interior=true, const unsigned int fe_component=0) const
Threads::ThreadLocalStorage< std::list< std::pair< bool, AlignedVector< VectorizedArrayType > > > > scratch_pad
void reinit(const Mapping< dim > &mapping, const DoFHandlerType &dof_handler, const AffineConstraints< number2 > &constraint, const QuadratureType &quad, const AdditionalData &additional_data=AdditionalData())
unsigned int minimum_parallel_grain_size
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
VectorizedArrayType vectorized_value_type
bool overlap_communication_computation
void export_to_ghosted_array_finish(const ArrayView< Number, MemorySpaceType > &ghost_array, std::vector< MPI_Request > &requests) const
internal::MatrixFreeFunctions::MappingInfo< dim, Number, VectorizedArrayType > mapping_info
AdditionalData & operator=(const AdditionalData &other)
static ::ExceptionBase & ExcNotImplemented()
void release_scratch_data(const AlignedVector< VectorizedArrayType > *memory) const
void release_scratch_data_non_threadsafe(const AlignedVector< Number > *memory) const
bool at_irregular_cell(const unsigned int macro_cell_number) const
std::vector< unsigned int > constraint_pool_row_index
std::vector< SmartPointer< const DoFHandler< dim > > > dof_handler
std::vector< std::pair< unsigned int, unsigned int > > cell_loop_post_list
static bool is_supported(const FiniteElement< dim, spacedim > &fe)
void loop_cell_centric(void(CLASS::*cell_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &) const, const CLASS *owning_class, OutVector &dst, const InVector &src, const bool zero_dst_vector=false, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified) const
unsigned int tasks_block_size
const Quadrature< dim > & get_quadrature(const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0) const
const internal::MatrixFreeFunctions::FaceToCellTopology< VectorizedArrayType::size()> & get_face_info(const unsigned int face_batch_number) const
unsigned int n_import_indices() const
#define DEAL_II_DEPRECATED
T max(const T &t, const MPI_Comm &mpi_communicator)
unsigned int cell_level_index_end_local
unsigned int n_physical_cells() const
void copy_from(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free_base)
static bool equal(const T *p1, const T *p2)
static ::ExceptionBase & ExcInternalError()