16#ifndef dealii_matrix_free_h
17#define dealii_matrix_free_h
110 typename Number = double,
115 std::is_same_v<Number, typename VectorizedArrayType::value_type>,
116 "Type of Number and of VectorizedArrayType do not match.");
587 template <
typename QuadratureType,
typename number2,
typename MappingType>
592 const QuadratureType &quad,
616 template <
typename QuadratureType,
typename number2,
typename MappingType>
621 const std::vector<QuadratureType> &quad,
631 template <
typename QuadratureType,
typename number2,
typename MappingType>
636 const QuadratureType &quad,
793 template <
typename OutVector,
typename InVector>
799 const std::pair<unsigned int, unsigned int> &)> &cell_operation,
802 const bool zero_dst_vector =
false)
const;
850 template <
typename CLASS,
typename OutVector,
typename InVector>
856 const
std::pair<unsigned
int, unsigned
int> &) const,
857 const CLASS *owning_class,
860 const
bool zero_dst_vector = false) const;
865 template <
typename CLASS,
typename OutVector,
typename InVector>
871 const
std::pair<unsigned
int, unsigned
int> &),
875 const
bool zero_dst_vector = false) const;
961 template <
typename CLASS,
typename OutVector,
typename InVector>
967 const
std::pair<unsigned
int, unsigned
int> &) const,
968 const CLASS *owning_class,
971 const
std::function<void(const unsigned
int, const unsigned
int)>
972 &operation_before_loop,
973 const
std::function<void(const unsigned
int, const unsigned
int)>
974 &operation_after_loop,
975 const unsigned
int dof_handler_index_pre_post = 0) const;
980 template <
typename CLASS,
typename OutVector,
typename InVector>
986 const
std::pair<unsigned
int, unsigned
int> &),
990 const
std::function<void(const unsigned
int, const unsigned
int)>
991 &operation_before_loop,
992 const
std::function<void(const unsigned
int, const unsigned
int)>
993 &operation_after_loop,
994 const unsigned
int dof_handler_index_pre_post = 0) const;
1000 template <
typename OutVector,
typename InVector>
1006 const std::pair<unsigned int, unsigned int> &)> &cell_operation,
1008 const InVector &src,
1009 const std::function<
void(
const unsigned int,
const unsigned int)>
1010 &operation_before_loop,
1011 const std::function<
void(
const unsigned int,
const unsigned int)>
1012 &operation_after_loop,
1013 const unsigned int dof_handler_index_pre_post = 0)
const;
1090 template <
typename OutVector,
typename InVector>
1093 const std::function<
1097 const std::pair<unsigned int, unsigned int> &)> &cell_operation,
1098 const std::function<
void(
1102 const std::pair<unsigned int, unsigned int> &)> &inner_face_operation,
1103 const std::function<
void(
1107 const std::pair<unsigned int, unsigned int> &)> &boundary_face_operation,
1109 const InVector &src,
1110 const bool zero_dst_vector =
false,
1204 template <
typename CLASS,
typename OutVector,
typename InVector>
1206 loop(
void (CLASS::*cell_operation)(
1210 const
std::pair<unsigned
int, unsigned
int> &) const,
1211 void (CLASS::*inner_face_operation)(
1215 const
std::pair<unsigned
int, unsigned
int> &) const,
1216 void (CLASS::*boundary_face_operation)(
1220 const
std::pair<unsigned
int, unsigned
int> &) const,
1221 const CLASS *owning_class,
1223 const InVector &src,
1224 const
bool zero_dst_vector = false,
1233 template <
typename CLASS,
typename OutVector,
typename InVector>
1235 loop(
void (CLASS::*cell_operation)(
1239 const
std::pair<unsigned
int, unsigned
int> &),
1240 void (CLASS::*inner_face_operation)(
1244 const
std::pair<unsigned
int, unsigned
int> &),
1245 void (CLASS::*boundary_face_operation)(
1249 const
std::pair<unsigned
int, unsigned
int> &),
1250 CLASS *owning_class,
1252 const InVector &src,
1253 const
bool zero_dst_vector = false,
1380 template <
typename CLASS,
typename OutVector,
typename InVector>
1382 loop(
void (CLASS::*cell_operation)(
1386 const
std::pair<unsigned
int, unsigned
int> &) const,
1387 void (CLASS::*inner_face_operation)(
1391 const
std::pair<unsigned
int, unsigned
int> &) const,
1392 void (CLASS::*boundary_face_operation)(
1396 const
std::pair<unsigned
int, unsigned
int> &) const,
1397 const CLASS *owning_class,
1399 const InVector &src,
1400 const
std::function<void(const unsigned
int, const unsigned
int)>
1401 &operation_before_loop,
1402 const
std::function<void(const unsigned
int, const unsigned
int)>
1403 &operation_after_loop,
1404 const unsigned
int dof_handler_index_pre_post = 0,
1413 template <
typename CLASS,
typename OutVector,
typename InVector>
1415 loop(
void (CLASS::*cell_operation)(
1419 const
std::pair<unsigned
int, unsigned
int> &),
1420 void (CLASS::*inner_face_operation)(
1424 const
std::pair<unsigned
int, unsigned
int> &),
1425 void (CLASS::*boundary_face_operation)(
1429 const
std::pair<unsigned
int, unsigned
int> &),
1430 const CLASS *owning_class,
1432 const InVector &src,
1433 const
std::function<void(const unsigned
int, const unsigned
int)>
1434 &operation_before_loop,
1435 const
std::function<void(const unsigned
int, const unsigned
int)>
1436 &operation_after_loop,
1437 const unsigned
int dof_handler_index_pre_post = 0,
1448 template <
typename OutVector,
typename InVector>
1451 const std::function<
1455 const std::pair<unsigned int, unsigned int> &)> &cell_operation,
1456 const std::function<
void(
1460 const std::pair<unsigned int, unsigned int> &)> &inner_face_operation,
1461 const std::function<
void(
1465 const std::pair<unsigned int, unsigned int> &)> &boundary_face_operation,
1467 const InVector &src,
1468 const std::function<
void(
const unsigned int,
const unsigned int)>
1469 &operation_before_loop,
1470 const std::function<
void(
const unsigned int,
const unsigned int)>
1471 &operation_after_loop,
1472 const unsigned int dof_handler_index_pre_post = 0,
1542 template <
typename CLASS,
typename OutVector,
typename InVector>
1548 const
std::pair<unsigned
int, unsigned
int> &) const,
1549 const CLASS *owning_class,
1551 const InVector &src,
1552 const
bool zero_dst_vector = false,
1559 template <
typename CLASS,
typename OutVector,
typename InVector>
1565 const
std::pair<unsigned
int, unsigned
int> &),
1566 CLASS *owning_class,
1568 const InVector &src,
1569 const
bool zero_dst_vector = false,
1576 template <
typename OutVector,
typename InVector>
1582 const std::pair<unsigned int, unsigned int> &)>
1585 const InVector &src,
1586 const bool zero_dst_vector =
false,
1597 std::pair<unsigned int, unsigned int>
1599 const unsigned int fe_degree,
1600 const unsigned int dof_handler_index = 0)
const;
1608 std::pair<unsigned int, unsigned int>
1610 const std::pair<unsigned int, unsigned int> &range,
1611 const unsigned int fe_index,
1612 const unsigned int dof_handler_index = 0)
const;
1625 const std::pair<unsigned int, unsigned int> range)
const;
1632 const bool is_interior_face =
true)
const;
1645 template <
typename T>
1654 template <
typename T>
1671 template <
typename VectorType>
1674 const unsigned int dof_handler_index = 0)
const;
1693 template <
typename Number2>
1696 const unsigned int dof_handler_index = 0)
const;
1708 const std::shared_ptr<const Utilities::MPI::Partitioner> &
1732 const std::vector<unsigned int> &
1747 const unsigned int dof_handler_index = 0);
1758 template <
int spacedim>
1857 const unsigned int face_number)
const;
1889 const unsigned int lane_index,
1890 const unsigned int dof_handler_index = 0)
const;
1899 const unsigned int lane_index)
const;
1923 std::pair<typename DoFHandler<dim>::cell_iterator,
unsigned int>
1925 const unsigned int lane_index,
1926 const bool interior =
true,
1927 const unsigned int fe_component = 0)
const;
1973 const unsigned int hp_active_fe_index = 0)
const;
1980 const unsigned int hp_active_fe_index = 0)
const;
1988 const unsigned int hp_active_fe_index = 0)
const;
1996 const unsigned int hp_active_fe_index = 0)
const;
2003 const unsigned int hp_active_fe_index = 0)
const;
2010 const unsigned int hp_active_fe_index = 0)
const;
2026 const std::pair<unsigned int, unsigned int> cell_batch_range)
const;
2032 std::pair<unsigned int, unsigned int>
2034 const std::pair<unsigned int, unsigned int> face_batch_range)
const;
2054 std::pair<unsigned int, unsigned int>
2088 template <
typename StreamType>
2116 const internal::MatrixFreeFunctions::
2117 MappingInfo<dim, Number, VectorizedArrayType> &
2152 const unsigned int quad_index = 0,
2153 const unsigned int fe_base_element = 0,
2154 const unsigned int hp_active_fe_index = 0,
2155 const unsigned int hp_active_quad_index = 0)
const;
2161 VectorizedArrayType::size()> &
2221 template <
typename number2,
int q_dim>
2227 const std::vector<IndexSet> &locally_owned_set,
2237 template <
typename number2>
2241 const std::vector<IndexSet> &locally_owned_set,
2269 std::vector<internal::MatrixFreeFunctions::DoFInfo>
dof_info;
2351 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>>
2358 mutable std::list<std::pair<bool, AlignedVector<Number>>>
2375template <
int dim,
typename Number,
typename VectorizedArrayType>
2376template <
typename T>
2381 vec.
resize(this->n_cell_batches() + this->n_ghost_cell_batches());
2386template <
int dim,
typename Number,
typename VectorizedArrayType>
2387template <
typename T>
2392 vec.
resize(this->n_inner_face_batches() + this->n_boundary_face_batches() +
2393 this->n_ghost_inner_face_batches());
2398template <
int dim,
typename Number,
typename VectorizedArrayType>
2399template <
typename VectorType>
2403 const unsigned int comp)
const
2406 "This function is not supported for block vectors.");
2408 Assert(task_info.n_procs == 1,
2409 ExcMessage(
"This function can only be used in serial."));
2412 vec.reinit(dof_info[comp].vector_partitioner->size());
2417template <
int dim,
typename Number,
typename VectorizedArrayType>
2418template <
typename Number2>
2422 const unsigned int comp)
const
2425 vec.
reinit(dof_info[comp].vector_partitioner, task_info.communicator_sm);
2430template <
int dim,
typename Number,
typename VectorizedArrayType>
2431inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
2433 const unsigned int comp)
const
2436 return dof_info[comp].vector_partitioner;
2441template <
int dim,
typename Number,
typename VectorizedArrayType>
2442inline const std::vector<unsigned int> &
2444 const unsigned int comp)
const
2447 return dof_info[comp].constrained_dofs;
2452template <
int dim,
typename Number,
typename VectorizedArrayType>
2457 return dof_handlers.size();
2462template <
int dim,
typename Number,
typename VectorizedArrayType>
2465 const unsigned int dof_no)
const
2469 return dof_handlers[dof_no]->get_fe().n_base_elements();
2474template <
int dim,
typename Number,
typename VectorizedArrayType>
2483template <
int dim,
typename Number,
typename VectorizedArrayType>
2487 return task_info.n_active_cells;
2492template <
int dim,
typename Number,
typename VectorizedArrayType>
2496 return *(task_info.cell_partition_data.end() - 2);
2501template <
int dim,
typename Number,
typename VectorizedArrayType>
2505 return *(task_info.cell_partition_data.end() - 1) -
2506 *(task_info.cell_partition_data.end() - 2);
2511template <
int dim,
typename Number,
typename VectorizedArrayType>
2515 if (task_info.face_partition_data.empty())
2517 return task_info.face_partition_data.back();
2522template <
int dim,
typename Number,
typename VectorizedArrayType>
2526 if (task_info.face_partition_data.empty())
2528 return task_info.boundary_partition_data.back() -
2529 task_info.face_partition_data.back();
2534template <
int dim,
typename Number,
typename VectorizedArrayType>
2538 if (task_info.face_partition_data.empty())
2540 return face_info.faces.size() - task_info.boundary_partition_data.back();
2545template <
int dim,
typename Number,
typename VectorizedArrayType>
2548 const unsigned int face_batch_index)
const
2550 Assert(face_batch_index >= task_info.boundary_partition_data[0] &&
2551 face_batch_index < task_info.boundary_partition_data.back(),
2553 task_info.boundary_partition_data[0],
2554 task_info.boundary_partition_data.back()));
2560template <
int dim,
typename Number,
typename VectorizedArrayType>
2563 const unsigned int cell_batch_index,
2564 const unsigned int face_number)
const
2568 Assert(face_info.cell_and_face_boundary_id.size(0) >= n_cell_batches(),
2572 for (
unsigned int v = 0;
2573 v < n_active_entries_per_cell_batch(cell_batch_index);
2576 face_info.cell_and_face_boundary_id(cell_batch_index, face_number, v);
2582template <
int dim,
typename Number,
typename VectorizedArrayType>
2583inline const internal::MatrixFreeFunctions::
2584 MappingInfo<dim, Number, VectorizedArrayType> &
2587 return mapping_info;
2592template <
int dim,
typename Number,
typename VectorizedArrayType>
2595 const unsigned int dof_index)
const
2598 return dof_info[dof_index];
2603template <
int dim,
typename Number,
typename VectorizedArrayType>
2607 return constraint_pool_row_index.size() - 1;
2612template <
int dim,
typename Number,
typename VectorizedArrayType>
2613inline const Number *
2615 const unsigned int row)
const
2618 return constraint_pool_data.empty() ?
2620 constraint_pool_data.data() + constraint_pool_row_index[row];
2625template <
int dim,
typename Number,
typename VectorizedArrayType>
2626inline const Number *
2628 const unsigned int row)
const
2631 return constraint_pool_data.empty() ?
2633 constraint_pool_data.data() + constraint_pool_row_index[row + 1];
2638template <
int dim,
typename Number,
typename VectorizedArrayType>
2639inline std::pair<unsigned int, unsigned int>
2641 const std::pair<unsigned int, unsigned int> &range,
2642 const unsigned int degree,
2643 const unsigned int dof_handler_component)
const
2645 if (dof_info[dof_handler_component].cell_active_fe_index.empty())
2648 dof_info[dof_handler_component].fe_index_conversion.size(), 1);
2650 dof_info[dof_handler_component].fe_index_conversion[0].size(), 1);
2651 if (dof_info[dof_handler_component].fe_index_conversion[0][0] == degree)
2654 return {range.second, range.second};
2657 const unsigned int fe_index =
2658 dof_info[dof_handler_component].fe_index_from_degree(0, degree);
2659 if (fe_index >= dof_info[dof_handler_component].max_fe_index)
2660 return {range.second, range.second};
2662 return create_cell_subrange_hp_by_index(range,
2664 dof_handler_component);
2669template <
int dim,
typename Number,
typename VectorizedArrayType>
2672 const unsigned int cell_batch_index)
const
2675 return VectorizedArrayType::size() > 1 &&
2676 cell_level_index[(cell_batch_index + 1) * VectorizedArrayType::size() -
2677 1] == cell_level_index[(cell_batch_index + 1) *
2678 VectorizedArrayType::size() -
2684template <
int dim,
typename Number,
typename VectorizedArrayType>
2688 return shape_info.size(2);
2692template <
int dim,
typename Number,
typename VectorizedArrayType>
2695 const std::pair<unsigned int, unsigned int> range)
const
2697 const auto &fe_indices = dof_info[0].cell_active_fe_index;
2699 if (fe_indices.empty() ==
true ||
2700 dof_handlers[0]->get_fe_collection().size() == 1)
2703 const auto index = fe_indices[range.first];
2705 for (
unsigned int i = range.first; i < range.second; ++i)
2713template <
int dim,
typename Number,
typename VectorizedArrayType>
2716 const std::pair<unsigned int, unsigned int> range,
2717 const bool is_interior_face)
const
2719 const auto &fe_indices = dof_info[0].cell_active_fe_index;
2721 if (fe_indices.empty() ==
true)
2724 if (is_interior_face)
2726 const unsigned int index =
2727 fe_indices[face_info.faces[range.first].cells_interior[0] /
2728 VectorizedArrayType::size()];
2730 for (
unsigned int i = range.first; i < range.second; ++i)
2732 fe_indices[face_info.faces[i].cells_interior[0] /
2733 VectorizedArrayType::size()]);
2739 const unsigned int index =
2740 fe_indices[face_info.faces[range.first].cells_exterior[0] /
2741 VectorizedArrayType::size()];
2743 for (
unsigned int i = range.first; i < range.second; ++i)
2745 fe_indices[face_info.faces[i].cells_exterior[0] /
2746 VectorizedArrayType::size()]);
2754template <
int dim,
typename Number,
typename VectorizedArrayType>
2757 const unsigned int cell_batch_index)
const
2761 const std::vector<unsigned char> &n_lanes_filled =
2762 dof_info[0].n_vectorization_lanes_filled
2766 return n_lanes_filled[cell_batch_index];
2771template <
int dim,
typename Number,
typename VectorizedArrayType>
2774 const unsigned int face_batch_index)
const
2778 const std::vector<unsigned char> &n_lanes_filled =
2779 dof_info[0].n_vectorization_lanes_filled
2782 return n_lanes_filled[face_batch_index];
2787template <
int dim,
typename Number,
typename VectorizedArrayType>
2790 const unsigned int dof_handler_index,
2791 const unsigned int active_fe_index)
const
2793 return dof_info[dof_handler_index].dofs_per_cell[active_fe_index];
2798template <
int dim,
typename Number,
typename VectorizedArrayType>
2801 const unsigned int quad_index,
2802 const unsigned int active_fe_index)
const
2805 return mapping_info.cell_data[quad_index]
2806 .descriptor[active_fe_index]
2812template <
int dim,
typename Number,
typename VectorizedArrayType>
2815 const unsigned int dof_handler_index,
2816 const unsigned int active_fe_index)
const
2818 return dof_info[dof_handler_index].dofs_per_face[active_fe_index];
2823template <
int dim,
typename Number,
typename VectorizedArrayType>
2826 const unsigned int quad_index,
2827 const unsigned int active_fe_index)
const
2830 return mapping_info.face_data[quad_index]
2831 .descriptor[active_fe_index]
2837template <
int dim,
typename Number,
typename VectorizedArrayType>
2840 const unsigned int dof_handler_index)
const
2842 return dof_info[dof_handler_index].vector_partitioner->locally_owned_range();
2847template <
int dim,
typename Number,
typename VectorizedArrayType>
2850 const unsigned int dof_handler_index)
const
2852 return dof_info[dof_handler_index].vector_partitioner->ghost_indices();
2857template <
int dim,
typename Number,
typename VectorizedArrayType>
2860 const unsigned int dof_handler_index,
2861 const unsigned int index_quad,
2862 const unsigned int index_fe,
2863 const unsigned int active_fe_index,
2864 const unsigned int active_quad_index)
const
2867 const unsigned int ind =
2868 dof_info[dof_handler_index].global_base_element_offset + index_fe;
2873 return shape_info(ind, index_quad, active_fe_index, active_quad_index);
2878template <
int dim,
typename Number,
typename VectorizedArrayType>
2880 VectorizedArrayType::size()> &
2882 const unsigned int face_batch_index)
const
2885 return face_info.faces[face_batch_index];
2890template <
int dim,
typename Number,
typename VectorizedArrayType>
2895 return face_info.cell_and_face_to_plain_faces;
2900template <
int dim,
typename Number,
typename VectorizedArrayType>
2903 const unsigned int quad_index,
2904 const unsigned int active_fe_index)
const
2907 return mapping_info.cell_data[quad_index]
2908 .descriptor[active_fe_index]
2914template <
int dim,
typename Number,
typename VectorizedArrayType>
2917 const unsigned int quad_index,
2918 const unsigned int active_fe_index)
const
2921 return mapping_info.face_data[quad_index]
2922 .descriptor[active_fe_index]
2928template <
int dim,
typename Number,
typename VectorizedArrayType>
2931 const std::pair<unsigned int, unsigned int> range)
const
2933 auto result = get_cell_category(range.first);
2935 for (
unsigned int i = range.first; i < range.second; ++i)
2936 result =
std::max(result, get_cell_category(i));
2943template <
int dim,
typename Number,
typename VectorizedArrayType>
2944inline std::pair<unsigned int, unsigned int>
2946 const std::pair<unsigned int, unsigned int> range)
const
2948 auto result = get_face_category(range.first);
2950 for (
unsigned int i = range.first; i < range.second; ++i)
2952 result.first =
std::max(result.first, get_face_category(i).
first);
2953 result.second =
std::max(result.second, get_face_category(i).
second);
2961template <
int dim,
typename Number,
typename VectorizedArrayType>
2964 const unsigned int cell_batch_index)
const
2967 AssertIndexRange(cell_batch_index, dof_info[0].cell_active_fe_index.size());
2968 if (dof_info[0].cell_active_fe_index.empty())
2971 return dof_info[0].cell_active_fe_index[cell_batch_index];
2976template <
int dim,
typename Number,
typename VectorizedArrayType>
2977inline std::pair<unsigned int, unsigned int>
2979 const unsigned int face_batch_index)
const
2982 if (dof_info[0].cell_active_fe_index.empty())
2983 return std::make_pair(0U, 0U);
2985 std::pair<unsigned int, unsigned int> result = std::make_pair(0U, 0U);
2986 for (
unsigned int v = 0;
2987 v < VectorizedArrayType::size() &&
2988 face_info.faces[face_batch_index].cells_interior[v] !=
2993 dof_info[0].cell_active_fe_index[face_info.faces[face_batch_index]
2994 .cells_interior[v] /
2995 VectorizedArrayType::size()]);
2996 if (face_info.faces[face_batch_index].cells_exterior[0] !=
2998 for (
unsigned int v = 0;
2999 v < VectorizedArrayType::size() &&
3000 face_info.faces[face_batch_index].cells_exterior[v] !=
3005 dof_info[0].cell_active_fe_index[face_info.faces[face_batch_index]
3006 .cells_exterior[v] /
3007 VectorizedArrayType::size()]);
3015template <
int dim,
typename Number,
typename VectorizedArrayType>
3019 return indices_are_initialized;
3024template <
int dim,
typename Number,
typename VectorizedArrayType>
3028 return mapping_is_initialized;
3032template <
int dim,
typename Number,
typename VectorizedArrayType>
3041template <
int dim,
typename Number,
typename VectorizedArrayType>
3046 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>;
3047 list_type &data = scratch_pad.get();
3048 for (
typename list_type::iterator it = data.begin(); it != data.end(); ++it)
3049 if (it->first ==
false)
3055 return &data.front().second;
3060template <
int dim,
typename Number,
typename VectorizedArrayType>
3066 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>;
3067 list_type &data = scratch_pad.get();
3068 for (
typename list_type::iterator it = data.begin(); it != data.end(); ++it)
3069 if (&it->second == scratch)
3080template <
int dim,
typename Number,
typename VectorizedArrayType>
3086 scratch_pad_non_threadsafe.
begin();
3087 it != scratch_pad_non_threadsafe.end();
3089 if (it->first ==
false)
3094 scratch_pad_non_threadsafe.push_front(
3096 return &scratch_pad_non_threadsafe.front().second;
3101template <
int dim,
typename Number,
typename VectorizedArrayType>
3108 scratch_pad_non_threadsafe.
begin();
3109 it != scratch_pad_non_threadsafe.end();
3111 if (&it->second == scratch)
3126 namespace MatrixFreeImplementation
3128 template <
int dim,
int spacedim>
3129 inline std::vector<IndexSet>
3130 extract_locally_owned_index_sets(
3132 const unsigned int level)
3134 std::vector<IndexSet> locally_owned_set;
3135 locally_owned_set.reserve(dofh.size());
3136 for (
unsigned int j = 0; j < dofh.size(); ++j)
3138 locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
3140 locally_owned_set.push_back(dofh[j]->locally_owned_mg_dofs(
level));
3141 return locally_owned_set;
3148template <
int dim,
typename Number,
typename VectorizedArrayType>
3149template <
typename QuadratureType,
typename number2,
typename MappingType>
3152 const MappingType &mapping,
3155 const QuadratureType &quad,
3159 std::vector<const DoFHandler<dim, dim> *> dof_handlers;
3160 std::vector<const AffineConstraints<number2> *> constraints;
3162 dof_handlers.push_back(&dof_handler);
3163 constraints.push_back(&constraints_in);
3165 std::vector<IndexSet> locally_owned_sets =
3166 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3167 dof_handlers, additional_data.
mg_level);
3169 std::vector<hp::QCollection<dim>> quad_hp;
3170 quad_hp.emplace_back(quad);
3182template <
int dim,
typename Number,
typename VectorizedArrayType>
3183template <
typename QuadratureType,
typename number2,
typename MappingType>
3186 const MappingType &mapping,
3189 const QuadratureType &quad,
3193 std::vector<IndexSet> locally_owned_set =
3194 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3195 dof_handler, additional_data.
mg_level);
3196 std::vector<hp::QCollection<dim>> quad_hp;
3197 quad_hp.emplace_back(quad);
3209template <
int dim,
typename Number,
typename VectorizedArrayType>
3210template <
typename QuadratureType,
typename number2,
typename MappingType>
3213 const MappingType &mapping,
3216 const std::vector<QuadratureType> &quad,
3220 std::vector<IndexSet> locally_owned_set =
3221 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3222 dof_handler, additional_data.
mg_level);
3223 std::vector<hp::QCollection<dim>> quad_hp;
3224 for (
unsigned int q = 0; q < quad.size(); ++q)
3225 quad_hp.emplace_back(quad[q]);
3252 template <
int dim,
typename Number,
typename VectorizedArrayType>
3253 struct VectorDataExchange
3260 static constexpr unsigned int channel_shift = 20;
3269 const ::MatrixFree<dim, Number, VectorizedArrayType> &matrix_free,
3270 const typename ::MatrixFree<dim, Number, VectorizedArrayType>::
3271 DataAccessOnFaces vector_face_access,
3272 const unsigned
int n_components)
3273 : matrix_free(matrix_free)
3274 , vector_face_access(
3275 matrix_free.get_task_info().face_partition_data.empty() ?
3276 ::
MatrixFree<dim, Number, VectorizedArrayType>::
3277 DataAccessOnFaces::unspecified :
3279 , ghosts_were_set(false)
3280# ifdef DEAL_II_WITH_MPI
3281 , tmp_data(n_components)
3282 , requests(n_components)
3286 if (this->vector_face_access !=
3288 DataAccessOnFaces::unspecified)
3289 for (unsigned
int c = 0; c < matrix_free.n_components(); ++c)
3291 matrix_free.get_dof_info(c).vector_exchanger_face_variants.size(),
3300 ~VectorDataExchange()
3302# ifdef DEAL_II_WITH_MPI
3303 for (
unsigned int i = 0; i < tmp_data.size(); ++i)
3304 if (tmp_data[i] !=
nullptr)
3305 matrix_free.release_scratch_data_non_threadsafe(tmp_data[i]);
3315 template <
typename VectorType>
3317 find_vector_in_mf(
const VectorType &vec,
3318 const bool check_global_compatibility =
true)
const
3321 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
3322 if (vec.get_partitioner().get() ==
3323 matrix_free.get_dof_info(c).vector_partitioner.get())
3327 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
3328 if (check_global_compatibility ?
3329 vec.get_partitioner()->is_globally_compatible(
3330 *matrix_free.get_dof_info(c).vector_partitioner) :
3331 vec.get_partitioner()->is_compatible(
3332 *matrix_free.get_dof_info(c).vector_partitioner))
3348 get_partitioner(
const unsigned int mf_component)
const
3351 .vector_exchanger_face_variants.size(),
3353 if (vector_face_access ==
3355 DataAccessOnFaces::
none)
3356 return *matrix_free.get_dof_info(mf_component)
3357 .vector_exchanger_face_variants[0];
3358 else if (vector_face_access ==
3360 DataAccessOnFaces::values)
3361 return *matrix_free.get_dof_info(mf_component)
3362 .vector_exchanger_face_variants[1];
3363 else if (vector_face_access ==
3366 return *matrix_free.get_dof_info(mf_component)
3367 .vector_exchanger_face_variants[2];
3368 else if (vector_face_access ==
3370 DataAccessOnFaces::values_all_faces)
3371 return *matrix_free.get_dof_info(mf_component)
3372 .vector_exchanger_face_variants[3];
3373 else if (vector_face_access ==
3375 DataAccessOnFaces::gradients_all_faces)
3376 return *matrix_free.get_dof_info(mf_component)
3377 .vector_exchanger_face_variants[4];
3379 return *matrix_free.get_dof_info(mf_component).vector_exchanger.get();
3387 template <
typename VectorType,
3388 std::enable_if_t<is_not_parallel_vector<VectorType>, VectorType>
3391 update_ghost_values_start(
const unsigned int ,
3392 const VectorType & )
3400 template <
typename VectorType,
3401 std::enable_if_t<!has_update_ghost_values_start<VectorType> &&
3402 !is_not_parallel_vector<VectorType>,
3403 VectorType> * =
nullptr>
3405 update_ghost_values_start(
const unsigned int component_in_block_vector,
3406 const VectorType &vec)
3408 (void)component_in_block_vector;
3409 const bool ghosts_set = vec.has_ghost_elements();
3411 Assert(matrix_free.get_task_info().allow_ghosted_vectors_in_loops ||
3412 ghosts_set ==
false,
3417 ghosts_were_set =
true;
3421 vec.update_ghost_values();
3431 template <
typename VectorType,
3432 std::enable_if_t<has_update_ghost_values_start<VectorType> &&
3433 !has_exchange_on_subset<VectorType>,
3434 VectorType> * =
nullptr>
3436 update_ghost_values_start(
const unsigned int component_in_block_vector,
3437 const VectorType &vec)
3439 (void)component_in_block_vector;
3440 const bool ghosts_set = vec.has_ghost_elements();
3442 Assert(matrix_free.get_task_info().allow_ghosted_vectors_in_loops ||
3443 ghosts_set ==
false,
3448 ghosts_were_set =
true;
3452 vec.update_ghost_values_start(component_in_block_vector + channel_shift);
3463 template <
typename VectorType,
3464 std::enable_if_t<has_update_ghost_values_start<VectorType> &&
3465 has_exchange_on_subset<VectorType>,
3466 VectorType> * =
nullptr>
3468 update_ghost_values_start(
const unsigned int component_in_block_vector,
3469 const VectorType &vec)
3471 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3472 "Type mismatch between VectorType and VectorDataExchange");
3473 (void)component_in_block_vector;
3474 const bool ghosts_set = vec.has_ghost_elements();
3476 Assert(matrix_free.get_task_info().allow_ghosted_vectors_in_loops ||
3477 ghosts_set ==
false,
3482 ghosts_were_set =
true;
3486 if (vec.size() != 0)
3488# ifdef DEAL_II_WITH_MPI
3489 const unsigned int mf_component = find_vector_in_mf(vec);
3491 const auto &part = get_partitioner(mf_component);
3493 if (part.n_ghost_indices() == 0 && part.n_import_indices() == 0 &&
3494 part.n_import_sm_procs() == 0)
3497 tmp_data[component_in_block_vector] =
3498 matrix_free.acquire_scratch_data_non_threadsafe();
3499 tmp_data[component_in_block_vector]->resize_fast(
3500 part.n_import_indices());
3503 part.export_to_ghosted_array_start(
3504 component_in_block_vector * 2 + channel_shift,
3506 vec.shared_vector_data(),
3508 part.locally_owned_size(),
3509 matrix_free.get_dof_info(mf_component)
3510 .vector_partitioner->n_ghost_indices()),
3512 part.n_import_indices()),
3513 this->requests[component_in_block_vector]);
3524 template <
typename VectorType,
3525 std::enable_if_t<!has_update_ghost_values_start<VectorType>,
3526 VectorType> * =
nullptr>
3528 update_ghost_values_finish(
const unsigned int ,
3529 const VectorType & )
3539 template <
typename VectorType,
3540 std::enable_if_t<has_update_ghost_values_start<VectorType> &&
3541 !has_exchange_on_subset<VectorType>,
3542 VectorType> * =
nullptr>
3544 update_ghost_values_finish(
const unsigned int component_in_block_vector,
3545 const VectorType &vec)
3547 (void)component_in_block_vector;
3549 if (ghosts_were_set)
3552 vec.update_ghost_values_finish();
3563 template <
typename VectorType,
3564 std::enable_if_t<has_update_ghost_values_start<VectorType> &&
3565 has_exchange_on_subset<VectorType>,
3566 VectorType> * =
nullptr>
3568 update_ghost_values_finish(
const unsigned int component_in_block_vector,
3569 const VectorType &vec)
3571 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3572 "Type mismatch between VectorType and VectorDataExchange");
3573 (void)component_in_block_vector;
3575 if (ghosts_were_set)
3578 if (vec.size() != 0)
3580# ifdef DEAL_II_WITH_MPI
3584 const unsigned int mf_component = find_vector_in_mf(vec);
3586 const auto &part = get_partitioner(mf_component);
3588 if (part.n_ghost_indices() != 0 || part.n_import_indices() != 0 ||
3589 part.n_import_sm_procs() != 0)
3591 part.export_to_ghosted_array_finish(
3593 vec.shared_vector_data(),
3595 part.locally_owned_size(),
3596 matrix_free.get_dof_info(mf_component)
3597 .vector_partitioner->n_ghost_indices()),
3598 this->requests[component_in_block_vector]);
3600 matrix_free.release_scratch_data_non_threadsafe(
3601 tmp_data[component_in_block_vector]);
3602 tmp_data[component_in_block_vector] =
nullptr;
3608 vec.set_ghost_state(
true);
3616 template <
typename VectorType,
3617 std::enable_if_t<is_not_parallel_vector<VectorType>, VectorType>
3620 compress_start(
const unsigned int ,
3630 template <
typename VectorType,
3631 std::enable_if_t<!has_compress_start<VectorType> &&
3632 !is_not_parallel_vector<VectorType>,
3633 VectorType> * =
nullptr>
3635 compress_start(
const unsigned int component_in_block_vector,
3638 (void)component_in_block_vector;
3650 template <
typename VectorType,
3651 std::enable_if_t<has_compress_start<VectorType> &&
3652 !has_exchange_on_subset<VectorType>,
3653 VectorType> * =
nullptr>
3655 compress_start(
const unsigned int component_in_block_vector,
3658 (void)component_in_block_vector;
3660 vec.compress_start(component_in_block_vector + channel_shift);
3671 template <
typename VectorType,
3672 std::enable_if_t<has_compress_start<VectorType> &&
3673 has_exchange_on_subset<VectorType>,
3674 VectorType> * =
nullptr>
3676 compress_start(
const unsigned int component_in_block_vector,
3679 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3680 "Type mismatch between VectorType and VectorDataExchange");
3681 (void)component_in_block_vector;
3684 if (vec.size() != 0)
3686# ifdef DEAL_II_WITH_MPI
3687 const unsigned int mf_component = find_vector_in_mf(vec);
3689 const auto &part = get_partitioner(mf_component);
3691 if (part.n_ghost_indices() == 0 && part.n_import_indices() == 0 &&
3692 part.n_import_sm_procs() == 0)
3695 tmp_data[component_in_block_vector] =
3696 matrix_free.acquire_scratch_data_non_threadsafe();
3697 tmp_data[component_in_block_vector]->resize_fast(
3698 part.n_import_indices());
3701 part.import_from_ghosted_array_start(
3703 component_in_block_vector * 2 + channel_shift,
3705 vec.shared_vector_data(),
3707 matrix_free.get_dof_info(mf_component)
3708 .vector_partitioner->n_ghost_indices()),
3710 part.n_import_indices()),
3711 this->requests[component_in_block_vector]);
3723 typename VectorType,
3724 std::enable_if_t<!has_compress_start<VectorType>, VectorType> * =
nullptr>
3726 compress_finish(
const unsigned int ,
3737 template <
typename VectorType,
3738 std::enable_if_t<has_compress_start<VectorType> &&
3739 !has_exchange_on_subset<VectorType>,
3740 VectorType> * =
nullptr>
3742 compress_finish(
const unsigned int component_in_block_vector,
3745 (void)component_in_block_vector;
3757 template <
typename VectorType,
3758 std::enable_if_t<has_compress_start<VectorType> &&
3759 has_exchange_on_subset<VectorType>,
3760 VectorType> * =
nullptr>
3762 compress_finish(
const unsigned int component_in_block_vector,
3765 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3766 "Type mismatch between VectorType and VectorDataExchange");
3767 (void)component_in_block_vector;
3768 if (vec.size() != 0)
3770# ifdef DEAL_II_WITH_MPI
3774 const unsigned int mf_component = find_vector_in_mf(vec);
3776 const auto &part = get_partitioner(mf_component);
3778 if (part.n_ghost_indices() != 0 || part.n_import_indices() != 0 ||
3779 part.n_import_sm_procs() != 0)
3781 part.import_from_ghosted_array_finish(
3784 vec.shared_vector_data(),
3786 matrix_free.get_dof_info(mf_component)
3787 .vector_partitioner->n_ghost_indices()),
3789 tmp_data[component_in_block_vector]->begin(),
3790 part.n_import_indices()),
3791 this->requests[component_in_block_vector]);
3793 matrix_free.release_scratch_data_non_threadsafe(
3794 tmp_data[component_in_block_vector]);
3795 tmp_data[component_in_block_vector] =
nullptr;
3801 MPI_Barrier(matrix_free.get_task_info().communicator_sm);
3813 template <
typename VectorType,
3814 std::enable_if_t<is_not_parallel_vector<VectorType>, VectorType>
3817 reset_ghost_values(
const VectorType & )
const
3826 template <
typename VectorType,
3827 std::enable_if_t<!has_exchange_on_subset<VectorType> &&
3828 !is_not_parallel_vector<VectorType>,
3829 VectorType> * =
nullptr>
3831 reset_ghost_values(
const VectorType &vec)
const
3833 if (ghosts_were_set ==
true)
3836 vec.zero_out_ghost_values();
3846 template <
typename VectorType,
3847 std::enable_if_t<has_exchange_on_subset<VectorType>, VectorType>
3850 reset_ghost_values(
const VectorType &vec)
const
3852 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3853 "Type mismatch between VectorType and VectorDataExchange");
3854 if (ghosts_were_set ==
true)
3857 if (vec.size() != 0)
3859# ifdef DEAL_II_WITH_MPI
3862 const unsigned int mf_component = find_vector_in_mf(vec);
3864 const auto &part = get_partitioner(mf_component);
3866 if (part.n_ghost_indices() > 0)
3871 part.locally_owned_size(),
3872 matrix_free.get_dof_info(mf_component)
3873 .vector_partitioner->n_ghost_indices()));
3879 vec.set_ghost_state(
false);
3889 template <
typename VectorType,
3890 std::enable_if_t<has_exchange_on_subset<VectorType>, VectorType>
3893 zero_vector_region(
const unsigned int range_index, VectorType &vec)
const
3895 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3896 "Type mismatch between VectorType and VectorDataExchange");
3901 const unsigned int mf_component = find_vector_in_mf(vec,
false);
3903 matrix_free.get_dof_info(mf_component);
3911 for (
unsigned int id =
3930 template <
typename VectorType,
3931 std::enable_if_t<!has_exchange_on_subset<VectorType>, VectorType>
3933 typename VectorType::value_type * =
nullptr>
3935 zero_vector_region(
const unsigned int range_index, VectorType &vec)
const
3939 if constexpr (std::is_same_v<
3943 for (
unsigned int i = 0; i < vec.size(); ++i)
3944 vec[i] =
typename VectorType::value_type();
3947 vec =
typename VectorType::value_type();
3958 zero_vector_region(
const unsigned int, ...)
const
3962 "which provide VectorType::value_type"));
3967 const ::MatrixFree<dim, Number, VectorizedArrayType> &matrix_free;
3968 const typename ::MatrixFree<dim, Number, VectorizedArrayType>::
3969 DataAccessOnFaces vector_face_access;
3970 bool ghosts_were_set;
3971# ifdef DEAL_II_WITH_MPI
3972 std::vector<AlignedVector<Number> *> tmp_data;
3973 std::vector<std::vector<MPI_Request>> requests;
3977 template <
typename VectorStruct>
3979 n_components(
const VectorStruct &vec);
3981 template <
typename VectorStruct>
3983 n_components_block(
const VectorStruct &vec,
const std::bool_constant<true>)
3985 unsigned int components = 0;
3986 for (
unsigned int bl = 0; bl < vec.n_blocks(); ++bl)
3987 components += n_components(vec.block(bl));
3991 template <
typename VectorStruct>
3993 n_components_block(
const VectorStruct &,
const std::bool_constant<false>)
3998 template <
typename VectorStruct>
4000 n_components(
const VectorStruct &vec)
4002 return n_components_block(
4006 template <
typename VectorStruct>
4008 n_components(
const std::vector<VectorStruct> &vec)
4010 unsigned int components = 0;
4011 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4012 components += n_components_block(
4017 template <
typename VectorStruct>
4019 n_components(
const std::vector<VectorStruct *> &vec)
4021 unsigned int components = 0;
4022 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4023 components += n_components_block(
4035 template <
typename VectorStruct,
4036 std::enable_if_t<!has_communication_block_size<VectorStruct>,
4037 VectorStruct> * =
nullptr>
4038 constexpr unsigned int
4039 get_communication_block_size(
const VectorStruct &)
4046 template <
typename VectorStruct,
4047 std::enable_if_t<has_communication_block_size<VectorStruct>,
4048 VectorStruct> * =
nullptr>
4049 constexpr unsigned int
4050 get_communication_block_size(
const VectorStruct &)
4052 return VectorStruct::communication_block_size;
4057 template <
typename VectorType,
4058 std::enable_if_t<is_not_parallel_vector<VectorType>, VectorType> * =
4061 has_ghost_elements(
const VectorType &vec)
4069 template <
typename VectorType,
4070 std::enable_if_t<!is_not_parallel_vector<VectorType>, VectorType>
4073 has_ghost_elements(
const VectorType &vec)
4075 return vec.has_ghost_elements();
4090 typename VectorStruct,
4092 typename VectorizedArrayType,
4093 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4096 update_ghost_values_start(
4097 const VectorStruct &vec,
4098 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4099 const unsigned int channel = 0)
4101 if (get_communication_block_size(vec) < vec.n_blocks())
4103 const bool ghosts_set = vec.has_ghost_elements();
4105 Assert(exchanger.matrix_free.get_task_info()
4106 .allow_ghosted_vectors_in_loops ||
4107 ghosts_set ==
false,
4112 exchanger.ghosts_were_set =
true;
4116 vec.update_ghost_values();
4120 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4121 update_ghost_values_start(vec.block(i), exchanger, channel + i);
4129 typename VectorStruct,
4131 typename VectorizedArrayType,
4132 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4135 update_ghost_values_start(
4136 const VectorStruct &vec,
4137 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4138 const unsigned int channel = 0)
4140 exchanger.update_ghost_values_start(channel, vec);
4147 typename VectorStruct,
4149 typename VectorizedArrayType>
4151 update_ghost_values_start(
4152 const std::vector<VectorStruct> &vec,
4153 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4155 unsigned int component_index = 0;
4156 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4158 update_ghost_values_start(vec[comp], exchanger, component_index);
4159 component_index += n_components(vec[comp]);
4167 typename VectorStruct,
4169 typename VectorizedArrayType>
4171 update_ghost_values_start(
4172 const std::vector<VectorStruct *> &vec,
4173 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4175 unsigned int component_index = 0;
4176 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4178 update_ghost_values_start(*vec[comp], exchanger, component_index);
4179 component_index += n_components(*vec[comp]);
4191 typename VectorStruct,
4193 typename VectorizedArrayType,
4194 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4197 update_ghost_values_finish(
4198 const VectorStruct &vec,
4199 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4200 const unsigned int channel = 0)
4202 if (get_communication_block_size(vec) < vec.n_blocks())
4208 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4209 update_ghost_values_finish(vec.block(i), exchanger, channel + i);
4216 typename VectorStruct,
4218 typename VectorizedArrayType,
4219 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4222 update_ghost_values_finish(
4223 const VectorStruct &vec,
4224 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4225 const unsigned int channel = 0)
4227 exchanger.update_ghost_values_finish(channel, vec);
4234 typename VectorStruct,
4236 typename VectorizedArrayType>
4238 update_ghost_values_finish(
4239 const std::vector<VectorStruct> &vec,
4240 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4242 unsigned int component_index = 0;
4243 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4245 update_ghost_values_finish(vec[comp], exchanger, component_index);
4246 component_index += n_components(vec[comp]);
4254 typename VectorStruct,
4256 typename VectorizedArrayType>
4258 update_ghost_values_finish(
4259 const std::vector<VectorStruct *> &vec,
4260 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4262 unsigned int component_index = 0;
4263 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4265 update_ghost_values_finish(*vec[comp], exchanger, component_index);
4266 component_index += n_components(*vec[comp]);
4278 typename VectorStruct,
4280 typename VectorizedArrayType,
4281 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4286 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4287 const unsigned int channel = 0)
4289 if (get_communication_block_size(vec) < vec.n_blocks())
4292 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4293 compress_start(vec.block(i), exchanger, channel + i);
4300 typename VectorStruct,
4302 typename VectorizedArrayType,
4303 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4308 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4309 const unsigned int channel = 0)
4311 exchanger.compress_start(channel, vec);
4318 typename VectorStruct,
4320 typename VectorizedArrayType>
4323 std::vector<VectorStruct> &vec,
4324 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4326 unsigned int component_index = 0;
4327 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4329 compress_start(vec[comp], exchanger, component_index);
4330 component_index += n_components(vec[comp]);
4338 typename VectorStruct,
4340 typename VectorizedArrayType>
4343 std::vector<VectorStruct *> &vec,
4344 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4346 unsigned int component_index = 0;
4347 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4349 compress_start(*vec[comp], exchanger, component_index);
4350 component_index += n_components(*vec[comp]);
4362 typename VectorStruct,
4364 typename VectorizedArrayType,
4365 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4370 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4371 const unsigned int channel = 0)
4373 if (get_communication_block_size(vec) < vec.n_blocks())
4379 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4380 compress_finish(vec.block(i), exchanger, channel + i);
4387 typename VectorStruct,
4389 typename VectorizedArrayType,
4390 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4395 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4396 const unsigned int channel = 0)
4398 exchanger.compress_finish(channel, vec);
4405 typename VectorStruct,
4407 typename VectorizedArrayType>
4410 std::vector<VectorStruct> &vec,
4411 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4413 unsigned int component_index = 0;
4414 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4416 compress_finish(vec[comp], exchanger, component_index);
4417 component_index += n_components(vec[comp]);
4425 typename VectorStruct,
4427 typename VectorizedArrayType>
4430 std::vector<VectorStruct *> &vec,
4431 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4433 unsigned int component_index = 0;
4434 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4436 compress_finish(*vec[comp], exchanger, component_index);
4437 component_index += n_components(*vec[comp]);
4453 typename VectorStruct,
4455 typename VectorizedArrayType,
4456 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4460 const VectorStruct &vec,
4461 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4464 if (exchanger.ghosts_were_set ==
true)
4467 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4468 reset_ghost_values(vec.block(i), exchanger);
4475 typename VectorStruct,
4477 typename VectorizedArrayType,
4478 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4482 const VectorStruct &vec,
4483 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4486 if (exchanger.ghosts_were_set ==
true)
4489 exchanger.reset_ghost_values(vec);
4496 typename VectorStruct,
4498 typename VectorizedArrayType>
4501 const std::vector<VectorStruct> &vec,
4502 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4505 if (exchanger.ghosts_were_set ==
true)
4508 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4509 reset_ghost_values(vec[comp], exchanger);
4516 typename VectorStruct,
4518 typename VectorizedArrayType>
4521 const std::vector<VectorStruct *> &vec,
4522 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4525 if (exchanger.ghosts_were_set ==
true)
4528 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4529 reset_ghost_values(*vec[comp], exchanger);
4540 typename VectorStruct,
4542 typename VectorizedArrayType,
4543 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4547 const unsigned int range_index,
4549 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4551 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4552 exchanger.zero_vector_region(range_index, vec.block(i));
4559 typename VectorStruct,
4561 typename VectorizedArrayType,
4562 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4566 const unsigned int range_index,
4568 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4570 exchanger.zero_vector_region(range_index, vec);
4577 typename VectorStruct,
4579 typename VectorizedArrayType>
4582 const unsigned int range_index,
4583 std::vector<VectorStruct> &vec,
4584 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4586 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4587 zero_vector_region(range_index, vec[comp], exchanger);
4594 typename VectorStruct,
4596 typename VectorizedArrayType>
4599 const unsigned int range_index,
4600 std::vector<VectorStruct *> &vec,
4601 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4603 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4604 zero_vector_region(range_index, *vec[comp], exchanger);
4612 template <
typename VectorStruct1,
typename VectorStruct2>
4614 apply_operation_to_constrained_dofs(
const std::vector<unsigned int> &,
4615 const VectorStruct1 &,
4619 template <
typename Number>
4621 apply_operation_to_constrained_dofs(
4622 const std::vector<unsigned int> &constrained_dofs,
4626 for (
const unsigned int i : constrained_dofs)
4627 dst.local_element(i) = src.local_element(i);
4631 namespace MatrixFreeFunctions
4635 template <
typename,
typename,
typename,
typename,
bool>
4636 struct InterfaceSelector
4640 template <
typename MF,
4644 struct InterfaceSelector<MF, InVector, OutVector, Container, true>
4646 using function_type = void (Container::*)(
4650 const
std::pair<unsigned
int, unsigned
int> &) const;
4654 template <
typename MF,
4658 struct InterfaceSelector<MF, InVector, OutVector, Container, false>
4660 using function_type =
4661 void (Container::*)(const MF &,
4664 const
std::pair<unsigned
int, unsigned
int> &);
4672 template <
typename MF,
4677 class MFWorker :
public MFWorkerInterface
4681 using function_type =
typename MatrixFreeFunctions::
4682 InterfaceSelector<MF, InVector, OutVector, Container, is_constant>::
4686 MFWorker(
const MF &matrix_free,
4687 const InVector &src,
4689 const bool zero_dst_vector_setting,
4690 const Container &container,
4691 function_type cell_function,
4692 function_type face_function,
4693 function_type boundary_function,
4694 const typename MF::DataAccessOnFaces src_vector_face_access =
4695 MF::DataAccessOnFaces::none,
4696 const typename MF::DataAccessOnFaces dst_vector_face_access =
4697 MF::DataAccessOnFaces::none,
4698 const std::function<
void(
const unsigned int,
const unsigned int)>
4699 &operation_before_loop = {},
4700 const std::function<void(
const unsigned int,
const unsigned int)>
4701 &operation_after_loop = {},
4702 const unsigned int dof_handler_index_pre_post = 0)
4703 : matrix_free(matrix_free)
4704 , container(const_cast<Container &>(container))
4705 , cell_function(cell_function)
4706 , face_function(face_function)
4707 , boundary_function(boundary_function)
4710 , src_data_exchanger(matrix_free,
4711 src_vector_face_access,
4713 , dst_data_exchanger(matrix_free,
4714 dst_vector_face_access,
4717 , zero_dst_vector_setting(zero_dst_vector_setting &&
4718 !src_and_dst_are_same)
4719 , operation_before_loop(operation_before_loop)
4720 , operation_after_loop(operation_after_loop)
4721 , dof_handler_index_pre_post(dof_handler_index_pre_post)
4723 Assert(!has_ghost_elements(dst),
4724 ExcMessage(
"The destination vector passed to the matrix-free "
4725 "loop is ghosted. This is not allowed."));
4730 cell(
const std::pair<unsigned int, unsigned int> &cell_range)
override
4732 if (cell_function !=
nullptr && cell_range.second > cell_range.first)
4733 for (
unsigned int i = 0; i < matrix_free.n_active_fe_indices(); ++i)
4735 const auto cell_subrange =
4736 matrix_free.create_cell_subrange_hp_by_index(cell_range, i);
4738 if (cell_subrange.second <= cell_subrange.first)
4742 cell_function)(matrix_free, this->dst, this->src, cell_subrange);
4747 cell(
const unsigned int range_index)
override
4749 process_range(cell_function,
4750 matrix_free.get_task_info().cell_partition_data_hp_ptr,
4751 matrix_free.get_task_info().cell_partition_data_hp,
4756 face(
const unsigned int range_index)
override
4758 process_range(face_function,
4759 matrix_free.get_task_info().face_partition_data_hp_ptr,
4760 matrix_free.get_task_info().face_partition_data_hp,
4765 boundary(
const unsigned int range_index)
override
4767 process_range(boundary_function,
4768 matrix_free.get_task_info().boundary_partition_data_hp_ptr,
4769 matrix_free.get_task_info().boundary_partition_data_hp,
4775 process_range(
const function_type &fu,
4776 const std::vector<unsigned int> &ptr,
4777 const std::vector<unsigned int> &data,
4778 const unsigned int range_index)
4784 for (
unsigned int i = ptr[range_index]; i < ptr[range_index + 1]; ++i)
4787 (container.*fu)(matrix_free,
4790 std::make_pair(data[2 * i], data[2 * i + 1]));
4802 vector_update_ghosts_start()
override
4804 if (!src_and_dst_are_same)
4805 internal::update_ghost_values_start(src, src_data_exchanger);
4810 vector_update_ghosts_finish()
override
4812 if (!src_and_dst_are_same)
4813 internal::update_ghost_values_finish(src, src_data_exchanger);
4818 vector_compress_start()
override
4820 internal::compress_start(dst, dst_data_exchanger);
4825 vector_compress_finish()
override
4827 internal::compress_finish(dst, dst_data_exchanger);
4828 if (!src_and_dst_are_same)
4829 internal::reset_ghost_values(src, src_data_exchanger);
4834 zero_dst_vector_range(
const unsigned int range_index)
override
4836 if (zero_dst_vector_setting)
4837 internal::zero_vector_region(range_index, dst, dst_data_exchanger);
4841 cell_loop_pre_range(
const unsigned int range_index)
override
4843 if (operation_before_loop)
4846 matrix_free.get_dof_info(dof_handler_index_pre_post);
4853 operation_before_loop,
4860 for (
unsigned int id =
4871 cell_loop_post_range(
const unsigned int range_index)
override
4873 if (operation_after_loop)
4877 const std::vector<unsigned int> &partition_row_index =
4878 matrix_free.get_task_info().partition_row_index;
4880 partition_row_index[partition_row_index.size() - 2] - 1)
4881 apply_operation_to_constrained_dofs(
4882 matrix_free.get_constrained_dofs(dof_handler_index_pre_post),
4887 matrix_free.get_dof_info(dof_handler_index_pre_post);
4894 operation_after_loop,
4901 for (
unsigned int id =
4912 const MF &matrix_free;
4913 Container &container;
4914 function_type cell_function;
4915 function_type face_function;
4916 function_type boundary_function;
4918 const InVector &src;
4920 VectorDataExchange<MF::dimension,
4921 typename MF::value_type,
4922 typename MF::vectorized_value_type>
4924 VectorDataExchange<MF::dimension,
4925 typename MF::value_type,
4926 typename MF::vectorized_value_type>
4928 const bool src_and_dst_are_same;
4929 const bool zero_dst_vector_setting;
4930 const std::function<void(
const unsigned int,
const unsigned int)>
4931 operation_before_loop;
4932 const std::function<void(
const unsigned int,
const unsigned int)>
4933 operation_after_loop;
4934 const unsigned int dof_handler_index_pre_post;
4943 template <
class MF,
typename InVector,
typename OutVector>
4944 struct MFClassWrapper
4946 using function_type =
4947 std::function<void(
const MF &,
4950 const std::pair<unsigned int, unsigned int> &)>;
4952 MFClassWrapper(
const function_type cell,
4953 const function_type face,
4954 const function_type boundary)
4957 , boundary(boundary)
4961 cell_integrator(
const MF &mf,
4963 const InVector &src,
4964 const std::pair<unsigned int, unsigned int> &range)
const
4967 cell(mf, dst, src, range);
4971 face_integrator(
const MF &mf,
4973 const InVector &src,
4974 const std::pair<unsigned int, unsigned int> &range)
const
4977 face(mf, dst, src, range);
4981 boundary_integrator(
4984 const InVector &src,
4985 const std::pair<unsigned int, unsigned int> &range)
const
4988 boundary(mf, dst, src, range);
4991 const function_type cell;
4992 const function_type face;
4993 const function_type boundary;
5000template <
int dim,
typename Number,
typename VectorizedArrayType>
5001template <
typename OutVector,
typename InVector>
5007 const std::pair<unsigned int, unsigned int> &)>
5010 const InVector &src,
5011 const bool zero_dst_vector)
const
5014 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5017 Wrapper wrap(cell_operation,
nullptr,
nullptr);
5018 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5028 &Wrapper::cell_integrator,
5029 &Wrapper::face_integrator,
5030 &Wrapper::boundary_integrator);
5032 task_info.loop(worker);
5037template <
int dim,
typename Number,
typename VectorizedArrayType>
5038template <
typename OutVector,
typename InVector>
5044 const std::pair<unsigned int, unsigned int> &)>
5047 const InVector &src,
5048 const std::function<
void(
const unsigned int,
const unsigned int)>
5049 &operation_before_loop,
5050 const std::function<
void(
const unsigned int,
const unsigned int)>
5051 &operation_after_loop,
5052 const unsigned int dof_handler_index_pre_post)
const
5055 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5058 Wrapper wrap(cell_operation,
nullptr,
nullptr);
5059 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5069 &Wrapper::cell_integrator,
5070 &Wrapper::face_integrator,
5071 &Wrapper::boundary_integrator,
5072 DataAccessOnFaces::none,
5073 DataAccessOnFaces::none,
5074 operation_before_loop,
5075 operation_after_loop,
5076 dof_handler_index_pre_post);
5078 task_info.loop(worker);
5083template <
int dim,
typename Number,
typename VectorizedArrayType>
5084template <
typename OutVector,
typename InVector>
5090 const std::pair<unsigned int, unsigned int> &)>
5095 const std::pair<unsigned int, unsigned int> &)>
5096 &inner_face_operation,
5100 const std::pair<unsigned int, unsigned int> &)>
5101 &boundary_face_operation,
5103 const InVector &src,
5104 const bool zero_dst_vector,
5105 const DataAccessOnFaces dst_vector_face_access,
5106 const DataAccessOnFaces src_vector_face_access)
const
5109 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5112 Wrapper wrap(cell_operation, inner_face_operation, boundary_face_operation);
5113 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5123 &Wrapper::cell_integrator,
5124 &Wrapper::face_integrator,
5125 &Wrapper::boundary_integrator,
5126 src_vector_face_access,
5127 dst_vector_face_access);
5129 task_info.loop(worker);
5134template <
int dim,
typename Number,
typename VectorizedArrayType>
5135template <
typename CLASS,
typename OutVector,
typename InVector>
5138 void (CLASS::*function_pointer)(
5139 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5142 const
std::pair<unsigned
int, unsigned
int> &) const,
5143 const CLASS *owning_class,
5145 const InVector &src,
5146 const
bool zero_dst_vector) const
5148 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5166template <
int dim,
typename Number,
typename VectorizedArrayType>
5167template <
typename CLASS,
typename OutVector,
typename InVector>
5170 void (CLASS::*function_pointer)(
5171 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5174 const
std::pair<unsigned
int, unsigned
int> &) const,
5175 const CLASS *owning_class,
5177 const InVector &src,
5178 const
std::function<void(const unsigned
int, const unsigned
int)>
5179 &operation_before_loop,
5180 const
std::function<void(const unsigned
int, const unsigned
int)>
5181 &operation_after_loop,
5182 const unsigned
int dof_handler_index_pre_post) const
5184 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5199 operation_before_loop,
5200 operation_after_loop,
5201 dof_handler_index_pre_post);
5207template <
int dim,
typename Number,
typename VectorizedArrayType>
5208template <
typename CLASS,
typename OutVector,
typename InVector>
5211 void (CLASS::*cell_operation)(
5212 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5215 const
std::pair<unsigned
int, unsigned
int> &) const,
5216 void (CLASS::*inner_face_operation)(
5217 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5220 const
std::pair<unsigned
int, unsigned
int> &) const,
5221 void (CLASS::*boundary_face_operation)(
5222 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5225 const
std::pair<unsigned
int, unsigned
int> &) const,
5226 const CLASS *owning_class,
5228 const InVector &src,
5229 const
bool zero_dst_vector,
5230 const DataAccessOnFaces dst_vector_face_access,
5231 const DataAccessOnFaces src_vector_face_access) const
5233 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5244 inner_face_operation,
5245 boundary_face_operation,
5246 src_vector_face_access,
5247 dst_vector_face_access);
5253template <
int dim,
typename Number,
typename VectorizedArrayType>
5254template <
typename CLASS,
typename OutVector,
typename InVector>
5257 void (CLASS::*function_pointer)(
5258 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5261 const
std::pair<unsigned
int, unsigned
int> &),
5262 CLASS *owning_class,
5264 const InVector &src,
5265 const
bool zero_dst_vector) const
5267 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5285template <
int dim,
typename Number,
typename VectorizedArrayType>
5286template <
typename CLASS,
typename OutVector,
typename InVector>
5289 void (CLASS::*function_pointer)(
5290 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5293 const
std::pair<unsigned
int, unsigned
int> &),
5294 CLASS *owning_class,
5296 const InVector &src,
5297 const
std::function<void(const unsigned
int, const unsigned
int)>
5298 &operation_before_loop,
5299 const
std::function<void(const unsigned
int, const unsigned
int)>
5300 &operation_after_loop,
5301 const unsigned
int dof_handler_index_pre_post) const
5303 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5318 operation_before_loop,
5319 operation_after_loop,
5320 dof_handler_index_pre_post);
5326template <
int dim,
typename Number,
typename VectorizedArrayType>
5327template <
typename CLASS,
typename OutVector,
typename InVector>
5330 void (CLASS::*cell_operation)(
5331 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5334 const
std::pair<unsigned
int, unsigned
int> &),
5335 void (CLASS::*inner_face_operation)(
5336 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5339 const
std::pair<unsigned
int, unsigned
int> &),
5340 void (CLASS::*boundary_face_operation)(
5341 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5344 const
std::pair<unsigned
int, unsigned
int> &),
5345 CLASS *owning_class,
5347 const InVector &src,
5348 const
bool zero_dst_vector,
5349 const DataAccessOnFaces dst_vector_face_access,
5350 const DataAccessOnFaces src_vector_face_access) const
5352 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5363 inner_face_operation,
5364 boundary_face_operation,
5365 src_vector_face_access,
5366 dst_vector_face_access);
5372template <
int dim,
typename Number,
typename VectorizedArrayType>
5373template <
typename OutVector,
typename InVector>
5379 const std::pair<unsigned int, unsigned int> &)>
5384 const std::pair<unsigned int, unsigned int> &)>
5385 &inner_face_operation,
5389 const std::pair<unsigned int, unsigned int> &)>
5390 &boundary_face_operation,
5392 const InVector &src,
5393 const std::function<
void(
const unsigned int,
const unsigned int)>
5394 &operation_before_loop,
5395 const std::function<
void(
const unsigned int,
const unsigned int)>
5396 &operation_after_loop,
5397 const unsigned int dof_handler_index_pre_post,
5398 const DataAccessOnFaces dst_vector_face_access,
5399 const DataAccessOnFaces src_vector_face_access)
const
5402 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5405 Wrapper wrap(cell_operation, inner_face_operation, boundary_face_operation);
5406 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5416 &Wrapper::cell_integrator,
5417 &Wrapper::face_integrator,
5418 &Wrapper::boundary_integrator,
5419 src_vector_face_access,
5420 dst_vector_face_access,
5421 operation_before_loop,
5422 operation_after_loop,
5423 dof_handler_index_pre_post);
5425 task_info.loop(worker);
5430template <
int dim,
typename Number,
typename VectorizedArrayType>
5431template <
typename CLASS,
typename OutVector,
typename InVector>
5434 void (CLASS::*cell_operation)(const
MatrixFree &,
5437 const
std::pair<unsigned
int, unsigned
int> &)
5439 void (CLASS::*inner_face_operation)(
5443 const
std::pair<unsigned
int, unsigned
int> &) const,
5444 void (CLASS::*boundary_face_operation)(
5448 const
std::pair<unsigned
int, unsigned
int> &) const,
5449 const CLASS *owning_class,
5451 const InVector &src,
5452 const
std::function<void(const unsigned
int, const unsigned
int)>
5453 &operation_before_loop,
5454 const
std::function<void(const unsigned
int, const unsigned
int)>
5455 &operation_after_loop,
5456 const unsigned
int dof_handler_index_pre_post,
5457 const DataAccessOnFaces dst_vector_face_access,
5458 const DataAccessOnFaces src_vector_face_access) const
5460 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5471 inner_face_operation,
5472 boundary_face_operation,
5473 src_vector_face_access,
5474 dst_vector_face_access,
5475 operation_before_loop,
5476 operation_after_loop,
5477 dof_handler_index_pre_post);
5483template <
int dim,
typename Number,
typename VectorizedArrayType>
5484template <
typename CLASS,
typename OutVector,
typename InVector>
5487 void (CLASS::*cell_operation)(const
MatrixFree &,
5490 const
std::pair<unsigned
int, unsigned
int> &),
5491 void (CLASS::*inner_face_operation)(
5495 const
std::pair<unsigned
int, unsigned
int> &),
5496 void (CLASS::*boundary_face_operation)(
5500 const
std::pair<unsigned
int, unsigned
int> &),
5501 const CLASS *owning_class,
5503 const InVector &src,
5504 const
std::function<void(const unsigned
int, const unsigned
int)>
5505 &operation_before_loop,
5506 const
std::function<void(const unsigned
int, const unsigned
int)>
5507 &operation_after_loop,
5508 const unsigned
int dof_handler_index_pre_post,
5509 const DataAccessOnFaces dst_vector_face_access,
5510 const DataAccessOnFaces src_vector_face_access) const
5512 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5523 inner_face_operation,
5524 boundary_face_operation,
5525 src_vector_face_access,
5526 dst_vector_face_access,
5527 operation_before_loop,
5528 operation_after_loop,
5529 dof_handler_index_pre_post);
5535template <
int dim,
typename Number,
typename VectorizedArrayType>
5536template <
typename CLASS,
typename OutVector,
typename InVector>
5539 void (CLASS::*function_pointer)(
5540 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5543 const
std::pair<unsigned
int, unsigned
int> &) const,
5544 const CLASS *owning_class,
5546 const InVector &src,
5547 const
bool zero_dst_vector,
5548 const DataAccessOnFaces src_vector_face_access) const
5550 auto src_vector_face_access_temp = src_vector_face_access;
5556 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5569 src_vector_face_access_temp,
5576template <
int dim,
typename Number,
typename VectorizedArrayType>
5577template <
typename CLASS,
typename OutVector,
typename InVector>
5580 void (CLASS::*function_pointer)(
5581 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5584 const
std::pair<unsigned
int, unsigned
int> &),
5585 CLASS *owning_class,
5587 const InVector &src,
5588 const
bool zero_dst_vector,
5589 const DataAccessOnFaces src_vector_face_access) const
5591 auto src_vector_face_access_temp = src_vector_face_access;
5597 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5610 src_vector_face_access_temp,
5617template <
int dim,
typename Number,
typename VectorizedArrayType>
5618template <
typename OutVector,
typename InVector>
5624 const std::pair<unsigned int, unsigned int> &)>
5627 const InVector &src,
5628 const bool zero_dst_vector,
5629 const DataAccessOnFaces src_vector_face_access)
const
5631 auto src_vector_face_access_temp = src_vector_face_access;
5632 if (DataAccessOnFaces::gradients == src_vector_face_access_temp)
5633 src_vector_face_access_temp = DataAccessOnFaces::gradients_all_faces;
5634 else if (DataAccessOnFaces::values == src_vector_face_access_temp)
5635 src_vector_face_access_temp = DataAccessOnFaces::values_all_faces;
5638 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5641 Wrapper wrap(cell_operation,
nullptr,
nullptr);
5643 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5653 &Wrapper::cell_integrator,
5654 &Wrapper::face_integrator,
5655 &Wrapper::boundary_integrator,
5656 src_vector_face_access_temp,
5657 DataAccessOnFaces::none);
5658 task_info.loop(worker);
void resize(const size_type new_size)
void reinit(const size_type size, const bool omit_zeroing_entries=false)
Abstract base class for mapping classes.
unsigned int n_active_fe_indices() const
std::pair< typename DoFHandler< dim >::cell_iterator, unsigned int > get_face_iterator(const unsigned int face_batch_index, const unsigned int lane_index, const bool interior=true, const unsigned int fe_component=0) const
void loop_cell_centric(void(CLASS::*cell_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), CLASS *owning_class, OutVector &dst, const InVector &src, const bool zero_dst_vector=false, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified) const
internal::MatrixFreeFunctions::MappingInfo< dim, Number, VectorizedArrayType > mapping_info
unsigned int get_cell_active_fe_index(const std::pair< unsigned int, unsigned int > range) const
const internal::MatrixFreeFunctions::TaskInfo & get_task_info() const
unsigned int n_ghost_cell_batches() const
void initialize_dof_handlers(const std::vector< const DoFHandler< dim, dim > * > &dof_handlers, const AdditionalData &additional_data)
types::boundary_id get_boundary_id(const unsigned int face_batch_index) const
void print(std::ostream &out) const
void update_mapping(const std::shared_ptr< hp::MappingCollection< dim > > &mapping)
const Table< 3, unsigned int > & get_cell_and_face_to_plain_faces() const
unsigned int n_inner_face_batches() const
unsigned int n_active_entries_per_cell_batch(const unsigned int cell_batch_index) const
void update_mapping(const Mapping< dim > &mapping)
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_index) const
unsigned int get_mg_level() const
void loop(void(CLASS::*cell_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &) const, void(CLASS::*inner_face_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &) const, void(CLASS::*boundary_face_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &) const, const CLASS *owning_class, OutVector &dst, const InVector &src, const std::function< void(const unsigned int, const unsigned int)> &operation_before_loop, const std::function< void(const unsigned int, const unsigned int)> &operation_after_loop, const unsigned int dof_handler_index_pre_post=0, const DataAccessOnFaces dst_vector_face_access=DataAccessOnFaces::unspecified, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified) const
void print_memory_consumption(StreamType &out) const
bool mapping_initialized() const
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 std::function< void(const unsigned int, const unsigned int)> &operation_before_loop, const std::function< void(const unsigned int, const unsigned int)> &operation_after_loop, const unsigned int dof_handler_index_pre_post=0) const
void internal_reinit(const std::shared_ptr< hp::MappingCollection< dim > > &mapping, const std::vector< const DoFHandler< dim, dim > * > &dof_handlers, const std::vector< const AffineConstraints< number2 > * > &constraint, const std::vector< IndexSet > &locally_owned_set, const std::vector< hp::QCollection< q_dim > > &quad, const AdditionalData &additional_data)
unsigned int get_n_q_points_face(const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0) 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 > &)> &inner_face_operation, const std::function< void(const MatrixFree< dim, Number, VectorizedArrayType > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &boundary_face_operation, OutVector &dst, const InVector &src, const std::function< void(const unsigned int, const unsigned int)> &operation_before_loop, const std::function< void(const unsigned int, const unsigned int)> &operation_after_loop, const unsigned int dof_handler_index_pre_post=0, const DataAccessOnFaces dst_vector_face_access=DataAccessOnFaces::unspecified, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified) const
const internal::MatrixFreeFunctions::DoFInfo & get_dof_info(const unsigned int dof_handler_index_component=0) const
AlignedVector< VectorizedArrayType > * acquire_scratch_data() const
bool at_irregular_cell(const unsigned int cell_batch_index) const
~MatrixFree() override=default
const AffineConstraints< Number > & get_affine_constraints(const unsigned int dof_handler_index=0) const
void copy_from(const MatrixFree< dim, Number, VectorizedArrayType > &matrix_free_base)
void initialize_face_data_vector(AlignedVector< T > &vec) const
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_constraint_pool_entries() const
void cell_loop(void(CLASS::*cell_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), CLASS *owning_class, OutVector &dst, const InVector &src, const std::function< void(const unsigned int, const unsigned int)> &operation_before_loop, const std::function< void(const unsigned int, const unsigned int)> &operation_after_loop, const unsigned int dof_handler_index_pre_post=0) const
const Number * constraint_pool_begin(const unsigned int pool_index) const
AlignedVector< Number > * acquire_scratch_data_non_threadsafe() const
const IndexSet & get_locally_owned_set(const unsigned int dof_handler_index=0) const
unsigned int get_dofs_per_face(const unsigned int dof_handler_index=0, const unsigned int hp_active_fe_index=0) const
internal::MatrixFreeFunctions::TaskInfo task_info
const DoFHandler< dim > & get_dof_handler(const unsigned int dof_handler_index=0) const
void release_scratch_data(const AlignedVector< VectorizedArrayType > *memory) const
void loop(void(CLASS::*cell_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &) const, void(CLASS::*inner_face_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &) const, void(CLASS::*boundary_face_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 dst_vector_face_access=DataAccessOnFaces::unspecified, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified) const
bool mapping_is_initialized
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
void initialize_dof_vector(LinearAlgebra::distributed::Vector< Number2 > &vec, const unsigned int dof_handler_index=0) const
DoFHandler< dim >::cell_iterator get_cell_iterator(const unsigned int cell_batch_index, const unsigned int lane_index, const unsigned int dof_handler_index=0) const
MatrixFree(const MatrixFree< dim, Number, VectorizedArrayType > &other)
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
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
std::pair< unsigned int, unsigned int > get_face_range_category(const std::pair< unsigned int, unsigned int > face_batch_range) const
void cell_loop(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 std::function< void(const unsigned int, const unsigned int)> &operation_before_loop, const std::function< void(const unsigned int, const unsigned int)> &operation_after_loop, const unsigned int dof_handler_index_pre_post=0) const
std::vector< std::pair< unsigned int, unsigned int > > cell_level_index
const std::shared_ptr< const Utilities::MPI::Partitioner > & get_vector_partitioner(const unsigned int dof_handler_index=0) const
const internal::MatrixFreeFunctions::MappingInfo< dim, Number, VectorizedArrayType > & get_mapping_info() const
std::vector< Number > constraint_pool_data
VectorizedArrayType vectorized_value_type
unsigned int n_cell_batches() const
const IndexSet & get_ghost_set(const unsigned int dof_handler_index=0) const
std::pair< int, int > get_cell_level_and_index(const unsigned int cell_batch_index, const unsigned int lane_index) const
bool indices_initialized() 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_cell_category(const unsigned int cell_batch_index) const
Threads::ThreadLocalStorage< std::list< std::pair< bool, AlignedVector< VectorizedArrayType > > > > scratch_pad
unsigned int get_matrix_free_cell_index(const typename Triangulation< dim >::cell_iterator &cell) const
std::size_t memory_consumption() const
std::pair< unsigned int, unsigned int > get_face_category(const unsigned int face_batch_index) const
unsigned int n_boundary_face_batches() const
void cell_loop(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
void loop(void(CLASS::*cell_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), void(CLASS::*inner_face_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), void(CLASS::*boundary_face_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), const CLASS *owning_class, OutVector &dst, const InVector &src, const std::function< void(const unsigned int, const unsigned int)> &operation_before_loop, const std::function< void(const unsigned int, const unsigned int)> &operation_after_loop, const unsigned int dof_handler_index_pre_post=0, const DataAccessOnFaces dst_vector_face_access=DataAccessOnFaces::unspecified, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified) const
std::list< std::pair< bool, AlignedVector< Number > > > scratch_pad_non_threadsafe
const Number * constraint_pool_end(const unsigned int pool_index) const
void loop_cell_centric(const std::function< void(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &cell_operation, OutVector &dst, const InVector &src, const bool zero_dst_vector=false, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified) const
std::vector< SmartPointer< const DoFHandler< dim > > > dof_handlers
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 > &)> &inner_face_operation, const std::function< void(const MatrixFree< dim, Number, VectorizedArrayType > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &boundary_face_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
void initialize_indices(const std::vector< const AffineConstraints< number2 > * > &constraint, const std::vector< IndexSet > &locally_owned_set, const AdditionalData &additional_data)
std::vector< SmartPointer< const AffineConstraints< Number > > > affine_constraints
unsigned int n_components() const
unsigned int n_physical_cells() const
void initialize_dof_vector(VectorType &vec, const unsigned int dof_handler_index=0) const
unsigned int get_n_q_points(const unsigned int quad_index=0, const unsigned int hp_active_fe_index=0) const
void reinit(const MappingType &mapping, const std::vector< const DoFHandler< dim > * > &dof_handler, const std::vector< const AffineConstraints< number2 > * > &constraint, const QuadratureType &quad, const AdditionalData &additional_data=AdditionalData())
std::vector< unsigned int > mf_cell_indices
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
void loop(void(CLASS::*cell_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), void(CLASS::*inner_face_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), void(CLASS::*boundary_face_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), CLASS *owning_class, 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
void cell_loop(void(CLASS::*cell_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), CLASS *owning_class, OutVector &dst, const InVector &src, const bool zero_dst_vector=false) const
std::vector< internal::MatrixFreeFunctions::DoFInfo > dof_info
void initialize_cell_data_vector(AlignedVector< T > &vec) const
unsigned int n_ghost_inner_face_batches() const
void release_scratch_data_non_threadsafe(const AlignedVector< Number > *memory) const
void renumber_dofs(std::vector< types::global_dof_index > &renumbering, const unsigned int dof_handler_index=0)
unsigned int get_face_active_fe_index(const std::pair< unsigned int, unsigned int > range, const bool is_interior_face=true) const
unsigned int n_active_entries_per_face_batch(const unsigned int face_batch_index) const
bool indices_are_initialized
internal::MatrixFreeFunctions::FaceInfo< VectorizedArrayType::size()> face_info
void reinit(const MappingType &mapping, const DoFHandler< dim > &dof_handler, const AffineConstraints< number2 > &constraint, const QuadratureType &quad, const AdditionalData &additional_data=AdditionalData())
unsigned int get_cell_range_category(const std::pair< unsigned int, unsigned int > cell_batch_range) const
void reinit(const MappingType &mapping, const std::vector< const DoFHandler< dim > * > &dof_handler, const std::vector< const AffineConstraints< number2 > * > &constraint, const std::vector< QuadratureType > &quad, const AdditionalData &additional_data=AdditionalData())
std::array< types::boundary_id, VectorizedArrayType::size()> get_faces_by_cells_boundary_id(const unsigned int cell_batch_index, const unsigned int face_number) const
std::vector< unsigned int > constraint_pool_row_index
const internal::MatrixFreeFunctions::ShapeInfo< 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
const std::vector< unsigned int > & get_constrained_dofs(const unsigned int dof_handler_index=0) const
unsigned int cell_level_index_end_local
unsigned int n_base_elements(const unsigned int dof_handler_index) const
Table< 4, internal::MatrixFreeFunctions::ShapeInfo< Number > > shape_info
static bool is_supported(const FiniteElement< dim, spacedim > &fe)
static constexpr unsigned int dimension
A class that provides a separate storage location on each thread that accesses the object.
unsigned int locally_owned_size() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcNotInitialized()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
typename ActiveSelector::cell_iterator cell_iterator
@ update_JxW_values
Transformed quadrature weights.
@ update_gradients
Shape function gradients.
@ update_default
No update.
VectorType::value_type * begin(VectorType &V)
unsigned int minimum_parallel_grain_size
const types::boundary_id invalid_boundary_id
static const unsigned int invalid_unsigned_int
void apply_to_subranges(const Iterator &begin, const std_cxx20::type_identity_t< Iterator > &end, const Function &f, const unsigned int grainsize)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
TasksParallelScheme tasks_parallel_scheme
bool hold_all_faces_to_owned_cells
UpdateFlags mapping_update_flags_inner_faces
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, const bool allow_ghosted_vectors_in_loops=true)
std::vector< unsigned int > cell_vectorization_category
AdditionalData & operator=(const AdditionalData &other)
bool cell_vectorization_categories_strict
UpdateFlags mapping_update_flags_boundary_faces
UpdateFlags mapping_update_flags
UpdateFlags mapping_update_flags_faces_by_cells
AdditionalData(const AdditionalData &other)
bool allow_ghosted_vectors_in_loops
unsigned int tasks_block_size
bool overlap_communication_computation
@ dof_access_face_interior
std::vector< unsigned int > cell_loop_pre_list_index
std::vector< unsigned int > cell_loop_post_list_index
std::vector< std::pair< unsigned int, unsigned int > > vector_zero_range_list
std::shared_ptr< const Utilities::MPI::Partitioner > vector_partitioner
std::vector< std::pair< unsigned int, unsigned int > > cell_loop_pre_list
std::vector< unsigned int > vector_zero_range_list_index
std::vector< std::pair< unsigned int, unsigned int > > cell_loop_post_list
void loop(MFWorkerInterface &worker) const