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,
2263 std::vector<ObserverPointer<const AffineConstraints<Number>>>
2270 std::vector<internal::MatrixFreeFunctions::DoFInfo>
dof_info;
2352 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>>
2359 mutable std::list<std::pair<bool, AlignedVector<Number>>>
2382template <
int dim,
typename Number,
typename VectorizedArrayType>
2383template <
typename T>
2388 vec.
resize(this->n_cell_batches() + this->n_ghost_cell_batches());
2393template <
int dim,
typename Number,
typename VectorizedArrayType>
2394template <
typename T>
2399 vec.
resize(this->n_inner_face_batches() + this->n_boundary_face_batches() +
2400 this->n_ghost_inner_face_batches());
2405template <
int dim,
typename Number,
typename VectorizedArrayType>
2406template <
typename VectorType>
2410 const unsigned int comp)
const
2413 "This function is not supported for block vectors.");
2415 Assert(task_info.n_procs == 1,
2416 ExcMessage(
"This function can only be used in serial."));
2419 vec.reinit(dof_info[comp].vector_partitioner->size());
2424template <
int dim,
typename Number,
typename VectorizedArrayType>
2425template <
typename Number2>
2429 const unsigned int comp)
const
2432 vec.
reinit(dof_info[comp].vector_partitioner, task_info.communicator_sm);
2437template <
int dim,
typename Number,
typename VectorizedArrayType>
2438inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
2440 const unsigned int comp)
const
2443 return dof_info[comp].vector_partitioner;
2448template <
int dim,
typename Number,
typename VectorizedArrayType>
2449inline const std::vector<unsigned int> &
2451 const unsigned int comp)
const
2454 return dof_info[comp].constrained_dofs;
2459template <
int dim,
typename Number,
typename VectorizedArrayType>
2464 return dof_handlers.size();
2469template <
int dim,
typename Number,
typename VectorizedArrayType>
2472 const unsigned int dof_no)
const
2476 return dof_handlers[dof_no]->get_fe().n_base_elements();
2481template <
int dim,
typename Number,
typename VectorizedArrayType>
2490template <
int dim,
typename Number,
typename VectorizedArrayType>
2494 return task_info.n_active_cells;
2499template <
int dim,
typename Number,
typename VectorizedArrayType>
2503 return *(task_info.cell_partition_data.end() - 2);
2508template <
int dim,
typename Number,
typename VectorizedArrayType>
2512 return *(task_info.cell_partition_data.end() - 1) -
2513 *(task_info.cell_partition_data.end() - 2);
2518template <
int dim,
typename Number,
typename VectorizedArrayType>
2522 if (task_info.face_partition_data.empty())
2524 return task_info.face_partition_data.back();
2529template <
int dim,
typename Number,
typename VectorizedArrayType>
2533 if (task_info.face_partition_data.empty())
2535 return task_info.boundary_partition_data.back() -
2536 task_info.face_partition_data.back();
2541template <
int dim,
typename Number,
typename VectorizedArrayType>
2545 if (task_info.face_partition_data.empty())
2547 return face_info.faces.size() - task_info.boundary_partition_data.back();
2552template <
int dim,
typename Number,
typename VectorizedArrayType>
2555 const unsigned int face_batch_index)
const
2557 Assert(face_batch_index >= task_info.boundary_partition_data[0] &&
2558 face_batch_index < task_info.boundary_partition_data.back(),
2560 task_info.boundary_partition_data[0],
2561 task_info.boundary_partition_data.back()));
2567template <
int dim,
typename Number,
typename VectorizedArrayType>
2570 const unsigned int cell_batch_index,
2571 const unsigned int face_number)
const
2575 Assert(face_info.cell_and_face_boundary_id.size(0) >= n_cell_batches(),
2579 for (
unsigned int v = 0;
2580 v < n_active_entries_per_cell_batch(cell_batch_index);
2583 face_info.cell_and_face_boundary_id(cell_batch_index, face_number, v);
2589template <
int dim,
typename Number,
typename VectorizedArrayType>
2590inline const internal::MatrixFreeFunctions::
2591 MappingInfo<dim, Number, VectorizedArrayType> &
2594 return mapping_info;
2599template <
int dim,
typename Number,
typename VectorizedArrayType>
2602 const unsigned int dof_index)
const
2605 return dof_info[dof_index];
2610template <
int dim,
typename Number,
typename VectorizedArrayType>
2614 return constraint_pool_row_index.size() - 1;
2619template <
int dim,
typename Number,
typename VectorizedArrayType>
2620inline const Number *
2622 const unsigned int row)
const
2625 return constraint_pool_data.empty() ?
2627 constraint_pool_data.data() + constraint_pool_row_index[row];
2632template <
int dim,
typename Number,
typename VectorizedArrayType>
2633inline const Number *
2635 const unsigned int row)
const
2638 return constraint_pool_data.empty() ?
2640 constraint_pool_data.data() + constraint_pool_row_index[row + 1];
2645template <
int dim,
typename Number,
typename VectorizedArrayType>
2646inline std::pair<unsigned int, unsigned int>
2648 const std::pair<unsigned int, unsigned int> &range,
2649 const unsigned int degree,
2650 const unsigned int dof_handler_component)
const
2652 if (dof_info[dof_handler_component].cell_active_fe_index.empty())
2655 dof_info[dof_handler_component].fe_index_conversion.size(), 1);
2657 dof_info[dof_handler_component].fe_index_conversion[0].
size(), 1);
2658 if (dof_info[dof_handler_component].fe_index_conversion[0][0] == degree)
2661 return {range.second, range.second};
2665 dof_info[dof_handler_component].fe_index_from_degree(0, degree);
2666 if (fe_index >= dof_info[dof_handler_component].max_fe_index)
2667 return {range.second, range.second};
2669 return create_cell_subrange_hp_by_index(range,
2671 dof_handler_component);
2676template <
int dim,
typename Number,
typename VectorizedArrayType>
2679 const unsigned int cell_batch_index)
const
2682 return VectorizedArrayType::size() > 1 &&
2683 cell_level_index[(cell_batch_index + 1) * VectorizedArrayType::size() -
2684 1] == cell_level_index[(cell_batch_index + 1) *
2685 VectorizedArrayType::size() -
2691template <
int dim,
typename Number,
typename VectorizedArrayType>
2695 return shape_info.size(2);
2699template <
int dim,
typename Number,
typename VectorizedArrayType>
2702 const std::pair<unsigned int, unsigned int> range)
const
2704 const auto &fe_indices =
2705 dof_info[first_hp_dof_handler_index].cell_active_fe_index;
2707 if (fe_indices.empty() ==
true ||
2708 dof_handlers[0]->get_fe_collection().size() == 1)
2711 const auto index = fe_indices[range.first];
2713 for (
unsigned int i = range.first; i < range.second; ++i)
2721template <
int dim,
typename Number,
typename VectorizedArrayType>
2724 const std::pair<unsigned int, unsigned int> range,
2725 const bool is_interior_face)
const
2727 const auto &fe_indices =
2728 dof_info[first_hp_dof_handler_index].cell_active_fe_index;
2730 if (fe_indices.empty() ==
true)
2733 if (is_interior_face)
2735 const unsigned int index =
2736 fe_indices[face_info.faces[range.first].cells_interior[0] /
2737 VectorizedArrayType::size()];
2739 for (
unsigned int i = range.first; i < range.second; ++i)
2741 fe_indices[face_info.faces[i].cells_interior[0] /
2742 VectorizedArrayType::size()]);
2748 const unsigned int index =
2749 fe_indices[face_info.faces[range.first].cells_exterior[0] /
2750 VectorizedArrayType::size()];
2752 for (
unsigned int i = range.first; i < range.second; ++i)
2754 fe_indices[face_info.faces[i].cells_exterior[0] /
2755 VectorizedArrayType::size()]);
2763template <
int dim,
typename Number,
typename VectorizedArrayType>
2766 const unsigned int cell_batch_index)
const
2770 const std::vector<unsigned char> &n_lanes_filled =
2771 dof_info[0].n_vectorization_lanes_filled
2775 return n_lanes_filled[cell_batch_index];
2780template <
int dim,
typename Number,
typename VectorizedArrayType>
2783 const unsigned int face_batch_index)
const
2787 const std::vector<unsigned char> &n_lanes_filled =
2788 dof_info[0].n_vectorization_lanes_filled
2791 return n_lanes_filled[face_batch_index];
2796template <
int dim,
typename Number,
typename VectorizedArrayType>
2799 const unsigned int dof_handler_index,
2800 const unsigned int active_fe_index)
const
2802 return dof_info[dof_handler_index].dofs_per_cell[active_fe_index];
2807template <
int dim,
typename Number,
typename VectorizedArrayType>
2810 const unsigned int quad_index,
2811 const unsigned int active_fe_index)
const
2814 return mapping_info.cell_data[quad_index]
2815 .descriptor[active_fe_index]
2821template <
int dim,
typename Number,
typename VectorizedArrayType>
2824 const unsigned int dof_handler_index,
2825 const unsigned int active_fe_index)
const
2827 return dof_info[dof_handler_index].dofs_per_face[active_fe_index];
2832template <
int dim,
typename Number,
typename VectorizedArrayType>
2835 const unsigned int quad_index,
2836 const unsigned int active_fe_index)
const
2839 return mapping_info.face_data[quad_index]
2840 .descriptor[active_fe_index]
2846template <
int dim,
typename Number,
typename VectorizedArrayType>
2849 const unsigned int dof_handler_index)
const
2851 return dof_info[dof_handler_index].vector_partitioner->locally_owned_range();
2856template <
int dim,
typename Number,
typename VectorizedArrayType>
2859 const unsigned int dof_handler_index)
const
2861 return dof_info[dof_handler_index].vector_partitioner->ghost_indices();
2866template <
int dim,
typename Number,
typename VectorizedArrayType>
2869 const unsigned int dof_handler_index,
2870 const unsigned int index_quad,
2871 const unsigned int index_fe,
2872 const unsigned int active_fe_index,
2873 const unsigned int active_quad_index)
const
2876 const unsigned int ind =
2877 dof_info[dof_handler_index].global_base_element_offset + index_fe;
2882 return shape_info(ind, index_quad, active_fe_index, active_quad_index);
2887template <
int dim,
typename Number,
typename VectorizedArrayType>
2889 VectorizedArrayType::size()> &
2891 const unsigned int face_batch_index)
const
2894 return face_info.faces[face_batch_index];
2899template <
int dim,
typename Number,
typename VectorizedArrayType>
2904 return face_info.cell_and_face_to_plain_faces;
2909template <
int dim,
typename Number,
typename VectorizedArrayType>
2912 const unsigned int quad_index,
2913 const unsigned int active_fe_index)
const
2916 return mapping_info.cell_data[quad_index]
2917 .descriptor[active_fe_index]
2923template <
int dim,
typename Number,
typename VectorizedArrayType>
2926 const unsigned int quad_index,
2927 const unsigned int active_fe_index)
const
2930 return mapping_info.face_data[quad_index]
2931 .descriptor[active_fe_index]
2937template <
int dim,
typename Number,
typename VectorizedArrayType>
2940 const std::pair<unsigned int, unsigned int> range)
const
2942 auto result = get_cell_category(range.first);
2944 for (
unsigned int i = range.first; i < range.second; ++i)
2945 result =
std::max(result, get_cell_category(i));
2952template <
int dim,
typename Number,
typename VectorizedArrayType>
2953inline std::pair<unsigned int, unsigned int>
2955 const std::pair<unsigned int, unsigned int> range)
const
2957 auto result = get_face_category(range.first);
2959 for (
unsigned int i = range.first; i < range.second; ++i)
2961 result.first =
std::max(result.first, get_face_category(i).
first);
2962 result.second =
std::max(result.second, get_face_category(i).
second);
2970template <
int dim,
typename Number,
typename VectorizedArrayType>
2973 const unsigned int cell_batch_index)
const
2978 dof_info[first_hp_dof_handler_index].cell_active_fe_index.size());
2979 if (dof_info[first_hp_dof_handler_index].cell_active_fe_index.empty())
2982 return dof_info[first_hp_dof_handler_index]
2983 .cell_active_fe_index[cell_batch_index];
2988template <
int dim,
typename Number,
typename VectorizedArrayType>
2989inline std::pair<unsigned int, unsigned int>
2991 const unsigned int face_batch_index)
const
2994 if (dof_info[first_hp_dof_handler_index].cell_active_fe_index.empty())
2995 return std::make_pair(0U, 0U);
2997 std::pair<unsigned int, unsigned int> result = std::make_pair(0U, 0U);
2998 for (
unsigned int v = 0;
2999 v < VectorizedArrayType::size() &&
3000 face_info.faces[face_batch_index].cells_interior[v] !=
3005 dof_info[first_hp_dof_handler_index].cell_active_fe_index
3006 [face_info.faces[face_batch_index].cells_interior[v] /
3007 VectorizedArrayType::size()]);
3008 if (face_info.faces[face_batch_index].cells_exterior[0] !=
3010 for (
unsigned int v = 0;
3011 v < VectorizedArrayType::size() &&
3012 face_info.faces[face_batch_index].cells_exterior[v] !=
3017 dof_info[first_hp_dof_handler_index].cell_active_fe_index
3018 [face_info.faces[face_batch_index].cells_exterior[v] /
3019 VectorizedArrayType::size()]);
3027template <
int dim,
typename Number,
typename VectorizedArrayType>
3031 return indices_are_initialized;
3036template <
int dim,
typename Number,
typename VectorizedArrayType>
3040 return mapping_is_initialized;
3044template <
int dim,
typename Number,
typename VectorizedArrayType>
3053template <
int dim,
typename Number,
typename VectorizedArrayType>
3058 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>;
3059 list_type &
data = scratch_pad.get();
3060 for (
typename list_type::iterator it =
data.begin(); it !=
data.end(); ++it)
3061 if (it->first ==
false)
3067 return &
data.front().second;
3072template <
int dim,
typename Number,
typename VectorizedArrayType>
3078 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>;
3079 list_type &
data = scratch_pad.get();
3080 for (
typename list_type::iterator it =
data.begin(); it !=
data.end(); ++it)
3081 if (&it->second == scratch)
3092template <
int dim,
typename Number,
typename VectorizedArrayType>
3098 scratch_pad_non_threadsafe.
begin();
3099 it != scratch_pad_non_threadsafe.end();
3101 if (it->first ==
false)
3106 scratch_pad_non_threadsafe.push_front(
3108 return &scratch_pad_non_threadsafe.front().second;
3113template <
int dim,
typename Number,
typename VectorizedArrayType>
3120 scratch_pad_non_threadsafe.
begin();
3121 it != scratch_pad_non_threadsafe.end();
3123 if (&it->second == scratch)
3138 namespace MatrixFreeImplementation
3140 template <
int dim,
int spacedim>
3141 inline std::vector<IndexSet>
3142 extract_locally_owned_index_sets(
3144 const unsigned int level)
3146 std::vector<IndexSet> locally_owned_set;
3147 locally_owned_set.reserve(dofh.size());
3148 for (
unsigned int j = 0; j < dofh.size(); ++j)
3150 locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
3152 locally_owned_set.push_back(dofh[j]->locally_owned_mg_dofs(
level));
3153 return locally_owned_set;
3160template <
int dim,
typename Number,
typename VectorizedArrayType>
3161template <
typename QuadratureType,
typename number2,
typename MappingType>
3164 const MappingType &mapping,
3167 const QuadratureType &quad,
3171 std::vector<const DoFHandler<dim, dim> *> dof_handlers;
3172 std::vector<const AffineConstraints<number2> *> constraints;
3174 dof_handlers.push_back(&dof_handler);
3175 constraints.push_back(&constraints_in);
3177 std::vector<IndexSet> locally_owned_sets =
3178 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3179 dof_handlers, additional_data.
mg_level);
3181 std::vector<hp::QCollection<dim>> quad_hp;
3182 quad_hp.emplace_back(quad);
3194template <
int dim,
typename Number,
typename VectorizedArrayType>
3195template <
typename QuadratureType,
typename number2,
typename MappingType>
3198 const MappingType &mapping,
3201 const QuadratureType &quad,
3205 std::vector<IndexSet> locally_owned_set =
3206 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3207 dof_handler, additional_data.
mg_level);
3208 std::vector<hp::QCollection<dim>> quad_hp;
3209 quad_hp.emplace_back(quad);
3221template <
int dim,
typename Number,
typename VectorizedArrayType>
3222template <
typename QuadratureType,
typename number2,
typename MappingType>
3225 const MappingType &mapping,
3228 const std::vector<QuadratureType> &quad,
3232 std::vector<IndexSet> locally_owned_set =
3233 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3234 dof_handler, additional_data.
mg_level);
3235 std::vector<hp::QCollection<dim>> quad_hp;
3236 for (
unsigned int q = 0; q < quad.size(); ++q)
3237 quad_hp.emplace_back(quad[q]);
3264 template <
int dim,
typename Number,
typename VectorizedArrayType>
3265 struct VectorDataExchange
3272 static constexpr unsigned int channel_shift = 20;
3281 const ::MatrixFree<dim, Number, VectorizedArrayType> &matrix_free,
3282 const typename ::MatrixFree<dim, Number, VectorizedArrayType>::
3283 DataAccessOnFaces vector_face_access,
3284 const unsigned
int n_components)
3285 : matrix_free(matrix_free)
3286 , vector_face_access(
3287 matrix_free.get_task_info().face_partition_data.empty() ?
3288 ::
MatrixFree<dim, Number, VectorizedArrayType>::
3289 DataAccessOnFaces::unspecified :
3291 , ghosts_were_set(false)
3292# ifdef DEAL_II_WITH_MPI
3293 , tmp_data(n_components)
3294 , requests(n_components)
3298 if (this->vector_face_access !=
3300 DataAccessOnFaces::unspecified)
3301 for (unsigned
int c = 0; c < matrix_free.n_components(); ++c)
3303 matrix_free.get_dof_info(c).vector_exchanger_face_variants.size(),
3312 ~VectorDataExchange()
3314# ifdef DEAL_II_WITH_MPI
3315 for (
unsigned int i = 0; i < tmp_data.size(); ++i)
3316 if (tmp_data[i] !=
nullptr)
3317 matrix_free.release_scratch_data_non_threadsafe(tmp_data[i]);
3327 template <
typename VectorType>
3329 find_vector_in_mf(
const VectorType &vec,
3330 const bool check_global_compatibility =
true)
const
3333 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
3334 if (vec.get_partitioner().get() ==
3335 matrix_free.get_dof_info(c).vector_partitioner.get())
3339 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
3340 if (check_global_compatibility ?
3341 vec.get_partitioner()->is_globally_compatible(
3342 *matrix_free.get_dof_info(c).vector_partitioner) :
3343 vec.get_partitioner()->is_compatible(
3344 *matrix_free.get_dof_info(c).vector_partitioner))
3360 get_partitioner(
const unsigned int mf_component)
const
3363 .vector_exchanger_face_variants.size(),
3365 if (vector_face_access ==
3367 DataAccessOnFaces::
none)
3368 return *matrix_free.get_dof_info(mf_component)
3369 .vector_exchanger_face_variants[0];
3370 else if (vector_face_access ==
3372 DataAccessOnFaces::
values)
3373 return *matrix_free.get_dof_info(mf_component)
3374 .vector_exchanger_face_variants[1];
3375 else if (vector_face_access ==
3378 return *matrix_free.get_dof_info(mf_component)
3379 .vector_exchanger_face_variants[2];
3380 else if (vector_face_access ==
3382 DataAccessOnFaces::values_all_faces)
3383 return *matrix_free.get_dof_info(mf_component)
3384 .vector_exchanger_face_variants[3];
3385 else if (vector_face_access ==
3387 DataAccessOnFaces::gradients_all_faces)
3388 return *matrix_free.get_dof_info(mf_component)
3389 .vector_exchanger_face_variants[4];
3391 return *matrix_free.get_dof_info(mf_component).vector_exchanger.get();
3400 std::enable_if_t<is_not_parallel_vector<VectorType>,
VectorType>
3403 update_ghost_values_start(
const unsigned int ,
3404 const VectorType & )
3413 std::enable_if_t<!has_update_ghost_values_start<VectorType> &&
3414 !is_not_parallel_vector<VectorType>,
3417 update_ghost_values_start(
const unsigned int component_in_block_vector,
3418 const VectorType &vec)
3420 (void)component_in_block_vector;
3421 const bool ghosts_set = vec.has_ghost_elements();
3423 Assert(matrix_free.get_task_info().allow_ghosted_vectors_in_loops ||
3424 ghosts_set ==
false,
3429 ghosts_were_set =
true;
3433 vec.update_ghost_values();
3444 std::enable_if_t<has_update_ghost_values_start<VectorType> &&
3445 !has_exchange_on_subset<VectorType>,
3448 update_ghost_values_start(
const unsigned int component_in_block_vector,
3449 const VectorType &vec)
3451 (void)component_in_block_vector;
3452 const bool ghosts_set = vec.has_ghost_elements();
3454 Assert(matrix_free.get_task_info().allow_ghosted_vectors_in_loops ||
3455 ghosts_set ==
false,
3460 ghosts_were_set =
true;
3464 vec.update_ghost_values_start(component_in_block_vector + channel_shift);
3476 std::enable_if_t<has_update_ghost_values_start<VectorType> &&
3477 has_exchange_on_subset<VectorType>,
3480 update_ghost_values_start(
const unsigned int component_in_block_vector,
3481 const VectorType &vec)
3483 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3484 "Type mismatch between VectorType and VectorDataExchange");
3485 (void)component_in_block_vector;
3486 const bool ghosts_set = vec.has_ghost_elements();
3488 Assert(matrix_free.get_task_info().allow_ghosted_vectors_in_loops ||
3489 ghosts_set ==
false,
3494 ghosts_were_set =
true;
3498 if (vec.size() != 0)
3500# ifdef DEAL_II_WITH_MPI
3501 const unsigned int mf_component = find_vector_in_mf(vec);
3503 const auto &part = get_partitioner(mf_component);
3505 if (part.n_ghost_indices() == 0 && part.n_import_indices() == 0 &&
3506 part.n_import_sm_procs() == 0)
3509 tmp_data[component_in_block_vector] =
3510 matrix_free.acquire_scratch_data_non_threadsafe();
3511 tmp_data[component_in_block_vector]->resize_fast(
3512 part.n_import_indices());
3515 part.export_to_ghosted_array_start(
3516 component_in_block_vector * 2 + channel_shift,
3518 vec.shared_vector_data(),
3520 part.locally_owned_size(),
3521 matrix_free.get_dof_info(mf_component)
3522 .vector_partitioner->n_ghost_indices()),
3524 part.n_import_indices()),
3525 this->requests[component_in_block_vector]);
3537 std::enable_if_t<!has_update_ghost_values_start<VectorType>,
3540 update_ghost_values_finish(
const unsigned int ,
3541 const VectorType & )
3552 std::enable_if_t<has_update_ghost_values_start<VectorType> &&
3553 !has_exchange_on_subset<VectorType>,
3556 update_ghost_values_finish(
const unsigned int component_in_block_vector,
3557 const VectorType &vec)
3559 (void)component_in_block_vector;
3561 if (ghosts_were_set)
3564 vec.update_ghost_values_finish();
3576 std::enable_if_t<has_update_ghost_values_start<VectorType> &&
3577 has_exchange_on_subset<VectorType>,
3580 update_ghost_values_finish(
const unsigned int component_in_block_vector,
3581 const VectorType &vec)
3583 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3584 "Type mismatch between VectorType and VectorDataExchange");
3585 (void)component_in_block_vector;
3587 if (ghosts_were_set)
3590 if (vec.size() != 0)
3592# ifdef DEAL_II_WITH_MPI
3596 const unsigned int mf_component = find_vector_in_mf(vec);
3598 const auto &part = get_partitioner(mf_component);
3600 if (part.n_ghost_indices() != 0 || part.n_import_indices() != 0 ||
3601 part.n_import_sm_procs() != 0)
3603 part.export_to_ghosted_array_finish(
3605 vec.shared_vector_data(),
3607 part.locally_owned_size(),
3608 matrix_free.get_dof_info(mf_component)
3609 .vector_partitioner->n_ghost_indices()),
3610 this->requests[component_in_block_vector]);
3612 matrix_free.release_scratch_data_non_threadsafe(
3613 tmp_data[component_in_block_vector]);
3614 tmp_data[component_in_block_vector] =
nullptr;
3620 vec.set_ghost_state(
true);
3629 std::enable_if_t<is_not_parallel_vector<VectorType>,
VectorType>
3632 compress_start(
const unsigned int ,
3643 std::enable_if_t<!has_compress_start<VectorType> &&
3644 !is_not_parallel_vector<VectorType>,
3647 compress_start(
const unsigned int component_in_block_vector,
3650 (void)component_in_block_vector;
3663 std::enable_if_t<has_compress_start<VectorType> &&
3664 !has_exchange_on_subset<VectorType>,
3667 compress_start(
const unsigned int component_in_block_vector,
3670 (void)component_in_block_vector;
3672 vec.compress_start(component_in_block_vector + channel_shift);
3684 std::enable_if_t<has_compress_start<VectorType> &&
3685 has_exchange_on_subset<VectorType>,
3688 compress_start(
const unsigned int component_in_block_vector,
3691 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3692 "Type mismatch between VectorType and VectorDataExchange");
3693 (void)component_in_block_vector;
3696 if (vec.size() != 0)
3698# ifdef DEAL_II_WITH_MPI
3699 const unsigned int mf_component = find_vector_in_mf(vec);
3701 const auto &part = get_partitioner(mf_component);
3703 if (part.n_ghost_indices() == 0 && part.n_import_indices() == 0 &&
3704 part.n_import_sm_procs() == 0)
3707 tmp_data[component_in_block_vector] =
3708 matrix_free.acquire_scratch_data_non_threadsafe();
3709 tmp_data[component_in_block_vector]->resize_fast(
3710 part.n_import_indices());
3713 part.import_from_ghosted_array_start(
3715 component_in_block_vector * 2 + channel_shift,
3717 vec.shared_vector_data(),
3719 matrix_free.get_dof_info(mf_component)
3720 .vector_partitioner->n_ghost_indices()),
3722 part.n_import_indices()),
3723 this->requests[component_in_block_vector]);
3736 std::enable_if_t<!has_compress_start<VectorType>,
VectorType> * =
nullptr>
3738 compress_finish(
const unsigned int ,
3750 std::enable_if_t<has_compress_start<VectorType> &&
3751 !has_exchange_on_subset<VectorType>,
3754 compress_finish(
const unsigned int component_in_block_vector,
3757 (void)component_in_block_vector;
3770 std::enable_if_t<has_compress_start<VectorType> &&
3771 has_exchange_on_subset<VectorType>,
3774 compress_finish(
const unsigned int component_in_block_vector,
3777 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3778 "Type mismatch between VectorType and VectorDataExchange");
3779 (void)component_in_block_vector;
3780 if (vec.size() != 0)
3782# ifdef DEAL_II_WITH_MPI
3786 const unsigned int mf_component = find_vector_in_mf(vec);
3788 const auto &part = get_partitioner(mf_component);
3790 if (part.n_ghost_indices() != 0 || part.n_import_indices() != 0 ||
3791 part.n_import_sm_procs() != 0)
3793 part.import_from_ghosted_array_finish(
3796 vec.shared_vector_data(),
3798 matrix_free.get_dof_info(mf_component)
3799 .vector_partitioner->n_ghost_indices()),
3801 tmp_data[component_in_block_vector]->begin(),
3802 part.n_import_indices()),
3803 this->requests[component_in_block_vector]);
3805 matrix_free.release_scratch_data_non_threadsafe(
3806 tmp_data[component_in_block_vector]);
3807 tmp_data[component_in_block_vector] =
nullptr;
3813 MPI_Barrier(matrix_free.get_task_info().communicator_sm);
3826 std::enable_if_t<is_not_parallel_vector<VectorType>,
VectorType>
3829 reset_ghost_values(
const VectorType & )
const
3839 std::enable_if_t<!has_exchange_on_subset<VectorType> &&
3840 !is_not_parallel_vector<VectorType>,
3843 reset_ghost_values(
const VectorType &vec)
const
3845 if (ghosts_were_set ==
true)
3848 vec.zero_out_ghost_values();
3859 std::enable_if_t<has_exchange_on_subset<VectorType>,
VectorType>
3862 reset_ghost_values(
const VectorType &vec)
const
3864 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3865 "Type mismatch between VectorType and VectorDataExchange");
3866 if (ghosts_were_set ==
true)
3869 if (vec.size() != 0)
3871# ifdef DEAL_II_WITH_MPI
3874 const unsigned int mf_component = find_vector_in_mf(vec);
3876 const auto &part = get_partitioner(mf_component);
3878 if (part.n_ghost_indices() > 0)
3880 part.reset_ghost_values(
3882 part.locally_owned_size(),
3883 matrix_free.get_dof_info(mf_component)
3884 .vector_partitioner->n_ghost_indices()));
3890 vec.set_ghost_state(
false);
3901 std::enable_if_t<has_exchange_on_subset<VectorType>,
VectorType>
3904 zero_vector_region(
const unsigned int range_index, VectorType &vec)
const
3906 static_assert(std::is_same_v<Number, typename VectorType::value_type>,
3907 "Type mismatch between VectorType and VectorDataExchange");
3912 const unsigned int mf_component = find_vector_in_mf(vec,
false);
3914 matrix_free.get_dof_info(mf_component);
3922 for (
unsigned int id =
3942 std::enable_if_t<!has_exchange_on_subset<VectorType>,
VectorType>
3944 typename VectorType::value_type * =
nullptr>
3946 zero_vector_region(
const unsigned int range_index, VectorType &vec)
const
3950 if constexpr (std::is_same_v<
3954 for (
unsigned int i = 0; i < vec.size(); ++i)
3955 vec[i] =
typename VectorType::value_type();
3958 vec =
typename VectorType::value_type();
3969 zero_vector_region(
const unsigned int, ...)
const
3973 "which provide VectorType::value_type"));
3978 const ::MatrixFree<dim, Number, VectorizedArrayType> &matrix_free;
3979 const typename ::MatrixFree<dim, Number, VectorizedArrayType>::
3980 DataAccessOnFaces vector_face_access;
3981 bool ghosts_were_set;
3982# ifdef DEAL_II_WITH_MPI
3983 std::vector<AlignedVector<Number> *> tmp_data;
3984 std::vector<std::vector<MPI_Request>> requests;
3988 template <
typename VectorStruct>
3990 n_components(
const VectorStruct &vec);
3992 template <
typename VectorStruct>
3994 n_components_block(
const VectorStruct &vec,
const std::bool_constant<true>)
3996 unsigned int components = 0;
3997 for (
unsigned int bl = 0; bl < vec.n_blocks(); ++bl)
3998 components += n_components(vec.block(bl));
4002 template <
typename VectorStruct>
4004 n_components_block(
const VectorStruct &,
const std::bool_constant<false>)
4009 template <
typename VectorStruct>
4011 n_components(
const VectorStruct &vec)
4013 return 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(
4028 template <
typename VectorStruct>
4030 n_components(
const std::vector<VectorStruct *> &vec)
4032 unsigned int components = 0;
4033 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4034 components += n_components_block(
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 &)
4057 template <
typename VectorStruct,
4058 std::enable_if_t<has_communication_block_size<VectorStruct>,
4059 VectorStruct> * =
nullptr>
4060 constexpr unsigned int
4061 get_communication_block_size(
const VectorStruct &)
4063 return VectorStruct::communication_block_size;
4069 std::enable_if_t<is_not_parallel_vector<VectorType>,
VectorType> * =
4072 has_ghost_elements(
const VectorType &vec)
4081 std::enable_if_t<!is_not_parallel_vector<VectorType>,
VectorType>
4084 has_ghost_elements(
const VectorType &vec)
4086 return vec.has_ghost_elements();
4101 typename VectorStruct,
4103 typename VectorizedArrayType,
4104 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4107 update_ghost_values_start(
4108 const VectorStruct &vec,
4109 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4110 const unsigned int channel = 0)
4112 if (get_communication_block_size(vec) < vec.n_blocks())
4114 const bool ghosts_set = vec.has_ghost_elements();
4116 Assert(exchanger.matrix_free.get_task_info()
4117 .allow_ghosted_vectors_in_loops ||
4118 ghosts_set ==
false,
4123 exchanger.ghosts_were_set =
true;
4127 vec.update_ghost_values();
4131 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4132 update_ghost_values_start(vec.block(i), exchanger, channel + i);
4140 typename VectorStruct,
4142 typename VectorizedArrayType,
4143 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4146 update_ghost_values_start(
4147 const VectorStruct &vec,
4148 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4149 const unsigned int channel = 0)
4151 exchanger.update_ghost_values_start(channel, vec);
4158 typename VectorStruct,
4160 typename VectorizedArrayType>
4162 update_ghost_values_start(
4163 const std::vector<VectorStruct> &vec,
4164 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4166 unsigned int component_index = 0;
4167 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4169 update_ghost_values_start(vec[comp], exchanger, component_index);
4170 component_index += n_components(vec[comp]);
4178 typename VectorStruct,
4180 typename VectorizedArrayType>
4182 update_ghost_values_start(
4183 const std::vector<VectorStruct *> &vec,
4184 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4186 unsigned int component_index = 0;
4187 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4189 update_ghost_values_start(*vec[comp], exchanger, component_index);
4190 component_index += n_components(*vec[comp]);
4202 typename VectorStruct,
4204 typename VectorizedArrayType,
4205 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4208 update_ghost_values_finish(
4209 const VectorStruct &vec,
4210 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4211 const unsigned int channel = 0)
4213 if (get_communication_block_size(vec) < vec.n_blocks())
4219 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4220 update_ghost_values_finish(vec.block(i), exchanger, channel + i);
4227 typename VectorStruct,
4229 typename VectorizedArrayType,
4230 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4233 update_ghost_values_finish(
4234 const VectorStruct &vec,
4235 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4236 const unsigned int channel = 0)
4238 exchanger.update_ghost_values_finish(channel, vec);
4245 typename VectorStruct,
4247 typename VectorizedArrayType>
4249 update_ghost_values_finish(
4250 const std::vector<VectorStruct> &vec,
4251 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4253 unsigned int component_index = 0;
4254 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4256 update_ghost_values_finish(vec[comp], exchanger, component_index);
4257 component_index += n_components(vec[comp]);
4265 typename VectorStruct,
4267 typename VectorizedArrayType>
4269 update_ghost_values_finish(
4270 const std::vector<VectorStruct *> &vec,
4271 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4273 unsigned int component_index = 0;
4274 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4276 update_ghost_values_finish(*vec[comp], exchanger, component_index);
4277 component_index += n_components(*vec[comp]);
4289 typename VectorStruct,
4291 typename VectorizedArrayType,
4292 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4297 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4298 const unsigned int channel = 0)
4300 if (get_communication_block_size(vec) < vec.n_blocks())
4303 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4304 compress_start(vec.block(i), exchanger, channel + i);
4311 typename VectorStruct,
4313 typename VectorizedArrayType,
4314 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4319 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4320 const unsigned int channel = 0)
4322 exchanger.compress_start(channel, vec);
4329 typename VectorStruct,
4331 typename VectorizedArrayType>
4334 std::vector<VectorStruct> &vec,
4335 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4337 unsigned int component_index = 0;
4338 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4340 compress_start(vec[comp], exchanger, component_index);
4341 component_index += n_components(vec[comp]);
4349 typename VectorStruct,
4351 typename VectorizedArrayType>
4354 std::vector<VectorStruct *> &vec,
4355 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4357 unsigned int component_index = 0;
4358 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4360 compress_start(*vec[comp], exchanger, component_index);
4361 component_index += n_components(*vec[comp]);
4373 typename VectorStruct,
4375 typename VectorizedArrayType,
4376 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4381 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4382 const unsigned int channel = 0)
4384 if (get_communication_block_size(vec) < vec.n_blocks())
4390 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4391 compress_finish(vec.block(i), exchanger, channel + i);
4398 typename VectorStruct,
4400 typename VectorizedArrayType,
4401 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4406 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4407 const unsigned int channel = 0)
4409 exchanger.compress_finish(channel, vec);
4416 typename VectorStruct,
4418 typename VectorizedArrayType>
4421 std::vector<VectorStruct> &vec,
4422 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4424 unsigned int component_index = 0;
4425 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4427 compress_finish(vec[comp], exchanger, component_index);
4428 component_index += n_components(vec[comp]);
4436 typename VectorStruct,
4438 typename VectorizedArrayType>
4441 std::vector<VectorStruct *> &vec,
4442 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4444 unsigned int component_index = 0;
4445 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4447 compress_finish(*vec[comp], exchanger, component_index);
4448 component_index += n_components(*vec[comp]);
4464 typename VectorStruct,
4466 typename VectorizedArrayType,
4467 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4471 const VectorStruct &vec,
4472 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4475 if (exchanger.ghosts_were_set ==
true)
4478 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4479 reset_ghost_values(vec.block(i), exchanger);
4486 typename VectorStruct,
4488 typename VectorizedArrayType,
4489 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4493 const VectorStruct &vec,
4494 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4497 if (exchanger.ghosts_were_set ==
true)
4500 exchanger.reset_ghost_values(vec);
4507 typename VectorStruct,
4509 typename VectorizedArrayType>
4512 const std::vector<VectorStruct> &vec,
4513 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4516 if (exchanger.ghosts_were_set ==
true)
4519 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4520 reset_ghost_values(vec[comp], exchanger);
4527 typename VectorStruct,
4529 typename VectorizedArrayType>
4532 const std::vector<VectorStruct *> &vec,
4533 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4536 if (exchanger.ghosts_were_set ==
true)
4539 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4540 reset_ghost_values(*vec[comp], exchanger);
4551 typename VectorStruct,
4553 typename VectorizedArrayType,
4554 std::enable_if_t<IsBlockVector<VectorStruct>::value, VectorStruct>
4558 const unsigned int range_index,
4560 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4562 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4563 exchanger.zero_vector_region(range_index, vec.block(i));
4570 typename VectorStruct,
4572 typename VectorizedArrayType,
4573 std::enable_if_t<!IsBlockVector<VectorStruct>::value, VectorStruct>
4577 const unsigned int range_index,
4579 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4581 exchanger.zero_vector_region(range_index, vec);
4588 typename VectorStruct,
4590 typename VectorizedArrayType>
4593 const unsigned int range_index,
4594 std::vector<VectorStruct> &vec,
4595 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4597 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4598 zero_vector_region(range_index, vec[comp], exchanger);
4605 typename VectorStruct,
4607 typename VectorizedArrayType>
4610 const unsigned int range_index,
4611 std::vector<VectorStruct *> &vec,
4612 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4614 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4615 zero_vector_region(range_index, *vec[comp], exchanger);
4623 template <
typename VectorStruct1,
typename VectorStruct2>
4625 apply_operation_to_constrained_dofs(
const std::vector<unsigned int> &,
4626 const VectorStruct1 &,
4630 template <
typename Number>
4632 apply_operation_to_constrained_dofs(
4633 const std::vector<unsigned int> &constrained_dofs,
4637 for (
const unsigned int i : constrained_dofs)
4638 dst.local_element(i) = src.local_element(i);
4642 namespace MatrixFreeFunctions
4646 template <
typename,
typename,
typename,
typename,
bool>
4647 struct InterfaceSelector
4651 template <
typename MF,
4655 struct InterfaceSelector<MF, InVector, OutVector, Container, true>
4657 using function_type = void (Container::*)(
4661 const
std::pair<unsigned
int, unsigned
int> &) const;
4665 template <
typename MF,
4669 struct InterfaceSelector<MF, InVector, OutVector, Container, false>
4671 using function_type =
4672 void (Container::*)(const MF &,
4675 const
std::pair<unsigned
int, unsigned
int> &);
4683 template <
typename MF,
4688 class MFWorker :
public MFWorkerInterface
4692 using function_type =
typename MatrixFreeFunctions::
4693 InterfaceSelector<MF, InVector, OutVector, Container, is_constant>::
4697 MFWorker(
const MF &matrix_free,
4698 const InVector &src,
4700 const bool zero_dst_vector_setting,
4701 const Container &container,
4702 function_type cell_function,
4703 function_type face_function,
4704 function_type boundary_function,
4705 const typename MF::DataAccessOnFaces src_vector_face_access =
4706 MF::DataAccessOnFaces::none,
4707 const typename MF::DataAccessOnFaces dst_vector_face_access =
4708 MF::DataAccessOnFaces::none,
4709 const std::function<
void(
const unsigned int,
const unsigned int)>
4710 &operation_before_loop = {},
4711 const std::function<void(
const unsigned int,
const unsigned int)>
4712 &operation_after_loop = {},
4713 const unsigned int dof_handler_index_pre_post = 0)
4714 : matrix_free(matrix_free)
4715 , container(const_cast<Container &>(container))
4716 , cell_function(cell_function)
4717 , face_function(face_function)
4718 , boundary_function(boundary_function)
4721 , src_data_exchanger(matrix_free,
4722 src_vector_face_access,
4724 , dst_data_exchanger(matrix_free,
4725 dst_vector_face_access,
4728 , zero_dst_vector_setting(zero_dst_vector_setting &&
4729 !src_and_dst_are_same)
4730 , operation_before_loop(operation_before_loop)
4731 , operation_after_loop(operation_after_loop)
4732 , dof_handler_index_pre_post(dof_handler_index_pre_post)
4734 Assert(!has_ghost_elements(dst),
4735 ExcMessage(
"The destination vector passed to the matrix-free "
4736 "loop is ghosted. This is not allowed."));
4741 cell(
const std::pair<unsigned int, unsigned int> &cell_range)
override
4743 if (cell_function !=
nullptr && cell_range.second > cell_range.first)
4744 for (
unsigned int i = 0; i < matrix_free.n_active_fe_indices(); ++i)
4746 const auto cell_subrange =
4747 matrix_free.create_cell_subrange_hp_by_index(cell_range, i);
4749 if (cell_subrange.second <= cell_subrange.first)
4753 cell_function)(matrix_free, this->dst, this->src, cell_subrange);
4758 cell(
const unsigned int range_index)
override
4760 process_range(cell_function,
4761 matrix_free.get_task_info().cell_partition_data_hp_ptr,
4762 matrix_free.get_task_info().cell_partition_data_hp,
4767 face(
const unsigned int range_index)
override
4769 process_range(face_function,
4770 matrix_free.get_task_info().face_partition_data_hp_ptr,
4771 matrix_free.get_task_info().face_partition_data_hp,
4776 boundary(
const unsigned int range_index)
override
4778 process_range(boundary_function,
4779 matrix_free.get_task_info().boundary_partition_data_hp_ptr,
4780 matrix_free.get_task_info().boundary_partition_data_hp,
4786 process_range(
const function_type &fu,
4787 const std::vector<unsigned int> &ptr,
4788 const std::vector<unsigned int> &
data,
4789 const unsigned int range_index)
4795 for (
unsigned int i = ptr[range_index]; i < ptr[range_index + 1]; ++i)
4798 (container.*fu)(matrix_free,
4801 std::make_pair(
data[2 * i],
data[2 * i + 1]));
4813 vector_update_ghosts_start()
override
4815 if (!src_and_dst_are_same)
4816 internal::update_ghost_values_start(src, src_data_exchanger);
4821 vector_update_ghosts_finish()
override
4823 if (!src_and_dst_are_same)
4824 internal::update_ghost_values_finish(src, src_data_exchanger);
4829 vector_compress_start()
override
4831 internal::compress_start(dst, dst_data_exchanger);
4836 vector_compress_finish()
override
4838 internal::compress_finish(dst, dst_data_exchanger);
4839 if (!src_and_dst_are_same)
4840 internal::reset_ghost_values(src, src_data_exchanger);
4845 zero_dst_vector_range(
const unsigned int range_index)
override
4847 if (zero_dst_vector_setting)
4848 internal::zero_vector_region(range_index, dst, dst_data_exchanger);
4852 cell_loop_pre_range(
const unsigned int range_index)
override
4854 if (operation_before_loop)
4857 matrix_free.get_dof_info(dof_handler_index_pre_post);
4864 operation_before_loop,
4871 for (
unsigned int id =
4882 cell_loop_post_range(
const unsigned int range_index)
override
4884 if (operation_after_loop)
4888 const std::vector<unsigned int> &partition_row_index =
4889 matrix_free.get_task_info().partition_row_index;
4891 partition_row_index[partition_row_index.size() - 2] - 1)
4892 apply_operation_to_constrained_dofs(
4893 matrix_free.get_constrained_dofs(dof_handler_index_pre_post),
4898 matrix_free.get_dof_info(dof_handler_index_pre_post);
4905 operation_after_loop,
4912 for (
unsigned int id =
4923 const MF &matrix_free;
4924 Container &container;
4925 function_type cell_function;
4926 function_type face_function;
4927 function_type boundary_function;
4929 const InVector &src;
4931 VectorDataExchange<MF::dimension,
4932 typename MF::value_type,
4933 typename MF::vectorized_value_type>
4935 VectorDataExchange<MF::dimension,
4936 typename MF::value_type,
4937 typename MF::vectorized_value_type>
4939 const bool src_and_dst_are_same;
4940 const bool zero_dst_vector_setting;
4941 const std::function<void(
const unsigned int,
const unsigned int)>
4942 operation_before_loop;
4943 const std::function<void(
const unsigned int,
const unsigned int)>
4944 operation_after_loop;
4945 const unsigned int dof_handler_index_pre_post;
4954 template <
class MF,
typename InVector,
typename OutVector>
4955 struct MFClassWrapper
4957 using function_type =
4958 std::function<void(
const MF &,
4961 const std::pair<unsigned int, unsigned int> &)>;
4963 MFClassWrapper(
const function_type cell,
4964 const function_type face,
4965 const function_type boundary)
4968 , boundary(boundary)
4972 cell_integrator(
const MF &mf,
4974 const InVector &src,
4975 const std::pair<unsigned int, unsigned int> &range)
const
4978 cell(mf, dst, src, range);
4982 face_integrator(
const MF &mf,
4984 const InVector &src,
4985 const std::pair<unsigned int, unsigned int> &range)
const
4988 face(mf, dst, src, range);
4992 boundary_integrator(
4995 const InVector &src,
4996 const std::pair<unsigned int, unsigned int> &range)
const
4999 boundary(mf, dst, src, range);
5002 const function_type cell;
5003 const function_type face;
5004 const function_type boundary;
5011template <
int dim,
typename Number,
typename VectorizedArrayType>
5012template <
typename OutVector,
typename InVector>
5018 const std::pair<unsigned int, unsigned int> &)>
5021 const InVector &src,
5022 const bool zero_dst_vector)
const
5025 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5028 Wrapper wrap(cell_operation,
nullptr,
nullptr);
5029 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5039 &Wrapper::cell_integrator,
5040 &Wrapper::face_integrator,
5041 &Wrapper::boundary_integrator);
5043 task_info.loop(worker);
5048template <
int dim,
typename Number,
typename VectorizedArrayType>
5049template <
typename OutVector,
typename InVector>
5055 const std::pair<unsigned int, unsigned int> &)>
5058 const InVector &src,
5059 const std::function<
void(
const unsigned int,
const unsigned int)>
5060 &operation_before_loop,
5061 const std::function<
void(
const unsigned int,
const unsigned int)>
5062 &operation_after_loop,
5063 const unsigned int dof_handler_index_pre_post)
const
5066 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5069 Wrapper wrap(cell_operation,
nullptr,
nullptr);
5070 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5080 &Wrapper::cell_integrator,
5081 &Wrapper::face_integrator,
5082 &Wrapper::boundary_integrator,
5083 DataAccessOnFaces::none,
5084 DataAccessOnFaces::none,
5085 operation_before_loop,
5086 operation_after_loop,
5087 dof_handler_index_pre_post);
5089 task_info.loop(worker);
5094template <
int dim,
typename Number,
typename VectorizedArrayType>
5095template <
typename OutVector,
typename InVector>
5101 const std::pair<unsigned int, unsigned int> &)>
5106 const std::pair<unsigned int, unsigned int> &)>
5107 &inner_face_operation,
5111 const std::pair<unsigned int, unsigned int> &)>
5112 &boundary_face_operation,
5114 const InVector &src,
5115 const bool zero_dst_vector,
5116 const DataAccessOnFaces dst_vector_face_access,
5117 const DataAccessOnFaces src_vector_face_access)
const
5120 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5123 Wrapper wrap(cell_operation, inner_face_operation, boundary_face_operation);
5124 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5134 &Wrapper::cell_integrator,
5135 &Wrapper::face_integrator,
5136 &Wrapper::boundary_integrator,
5137 src_vector_face_access,
5138 dst_vector_face_access);
5140 task_info.loop(worker);
5145template <
int dim,
typename Number,
typename VectorizedArrayType>
5146template <
typename CLASS,
typename OutVector,
typename InVector>
5149 void (CLASS::*function_pointer)(
5150 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5153 const
std::pair<unsigned
int, unsigned
int> &) const,
5154 const CLASS *owning_class,
5156 const InVector &src,
5157 const
bool zero_dst_vector) const
5159 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5177template <
int dim,
typename Number,
typename VectorizedArrayType>
5178template <
typename CLASS,
typename OutVector,
typename InVector>
5181 void (CLASS::*function_pointer)(
5182 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5185 const
std::pair<unsigned
int, unsigned
int> &) const,
5186 const CLASS *owning_class,
5188 const InVector &src,
5189 const
std::function<void(const unsigned
int, const unsigned
int)>
5190 &operation_before_loop,
5191 const
std::function<void(const unsigned
int, const unsigned
int)>
5192 &operation_after_loop,
5193 const unsigned
int dof_handler_index_pre_post) const
5195 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5210 operation_before_loop,
5211 operation_after_loop,
5212 dof_handler_index_pre_post);
5218template <
int dim,
typename Number,
typename VectorizedArrayType>
5219template <
typename CLASS,
typename OutVector,
typename InVector>
5222 void (CLASS::*cell_operation)(
5223 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5226 const
std::pair<unsigned
int, unsigned
int> &) const,
5227 void (CLASS::*inner_face_operation)(
5228 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5231 const
std::pair<unsigned
int, unsigned
int> &) const,
5232 void (CLASS::*boundary_face_operation)(
5233 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5236 const
std::pair<unsigned
int, unsigned
int> &) const,
5237 const CLASS *owning_class,
5239 const InVector &src,
5240 const
bool zero_dst_vector,
5241 const DataAccessOnFaces dst_vector_face_access,
5242 const DataAccessOnFaces src_vector_face_access) const
5244 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5255 inner_face_operation,
5256 boundary_face_operation,
5257 src_vector_face_access,
5258 dst_vector_face_access);
5264template <
int dim,
typename Number,
typename VectorizedArrayType>
5265template <
typename CLASS,
typename OutVector,
typename InVector>
5268 void (CLASS::*function_pointer)(
5269 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5272 const
std::pair<unsigned
int, unsigned
int> &),
5273 CLASS *owning_class,
5275 const InVector &src,
5276 const
bool zero_dst_vector) const
5278 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5296template <
int dim,
typename Number,
typename VectorizedArrayType>
5297template <
typename CLASS,
typename OutVector,
typename InVector>
5300 void (CLASS::*function_pointer)(
5301 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5304 const
std::pair<unsigned
int, unsigned
int> &),
5305 CLASS *owning_class,
5307 const InVector &src,
5308 const
std::function<void(const unsigned
int, const unsigned
int)>
5309 &operation_before_loop,
5310 const
std::function<void(const unsigned
int, const unsigned
int)>
5311 &operation_after_loop,
5312 const unsigned
int dof_handler_index_pre_post) const
5314 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5329 operation_before_loop,
5330 operation_after_loop,
5331 dof_handler_index_pre_post);
5337template <
int dim,
typename Number,
typename VectorizedArrayType>
5338template <
typename CLASS,
typename OutVector,
typename InVector>
5341 void (CLASS::*cell_operation)(
5342 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5345 const
std::pair<unsigned
int, unsigned
int> &),
5346 void (CLASS::*inner_face_operation)(
5347 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5350 const
std::pair<unsigned
int, unsigned
int> &),
5351 void (CLASS::*boundary_face_operation)(
5352 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5355 const
std::pair<unsigned
int, unsigned
int> &),
5356 CLASS *owning_class,
5358 const InVector &src,
5359 const
bool zero_dst_vector,
5360 const DataAccessOnFaces dst_vector_face_access,
5361 const DataAccessOnFaces src_vector_face_access) const
5363 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5374 inner_face_operation,
5375 boundary_face_operation,
5376 src_vector_face_access,
5377 dst_vector_face_access);
5383template <
int dim,
typename Number,
typename VectorizedArrayType>
5384template <
typename OutVector,
typename InVector>
5390 const std::pair<unsigned int, unsigned int> &)>
5395 const std::pair<unsigned int, unsigned int> &)>
5396 &inner_face_operation,
5400 const std::pair<unsigned int, unsigned int> &)>
5401 &boundary_face_operation,
5403 const InVector &src,
5404 const std::function<
void(
const unsigned int,
const unsigned int)>
5405 &operation_before_loop,
5406 const std::function<
void(
const unsigned int,
const unsigned int)>
5407 &operation_after_loop,
5408 const unsigned int dof_handler_index_pre_post,
5409 const DataAccessOnFaces dst_vector_face_access,
5410 const DataAccessOnFaces src_vector_face_access)
const
5413 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5416 Wrapper wrap(cell_operation, inner_face_operation, boundary_face_operation);
5417 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5427 &Wrapper::cell_integrator,
5428 &Wrapper::face_integrator,
5429 &Wrapper::boundary_integrator,
5430 src_vector_face_access,
5431 dst_vector_face_access,
5432 operation_before_loop,
5433 operation_after_loop,
5434 dof_handler_index_pre_post);
5436 task_info.loop(worker);
5441template <
int dim,
typename Number,
typename VectorizedArrayType>
5442template <
typename CLASS,
typename OutVector,
typename InVector>
5445 void (CLASS::*cell_operation)(const
MatrixFree &,
5448 const
std::pair<unsigned
int, unsigned
int> &)
5450 void (CLASS::*inner_face_operation)(
5454 const
std::pair<unsigned
int, unsigned
int> &) const,
5455 void (CLASS::*boundary_face_operation)(
5459 const
std::pair<unsigned
int, unsigned
int> &) const,
5460 const CLASS *owning_class,
5462 const InVector &src,
5463 const
std::function<void(const unsigned
int, const unsigned
int)>
5464 &operation_before_loop,
5465 const
std::function<void(const unsigned
int, const unsigned
int)>
5466 &operation_after_loop,
5467 const unsigned
int dof_handler_index_pre_post,
5468 const DataAccessOnFaces dst_vector_face_access,
5469 const DataAccessOnFaces src_vector_face_access) const
5471 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5482 inner_face_operation,
5483 boundary_face_operation,
5484 src_vector_face_access,
5485 dst_vector_face_access,
5486 operation_before_loop,
5487 operation_after_loop,
5488 dof_handler_index_pre_post);
5494template <
int dim,
typename Number,
typename VectorizedArrayType>
5495template <
typename CLASS,
typename OutVector,
typename InVector>
5498 void (CLASS::*cell_operation)(const
MatrixFree &,
5501 const
std::pair<unsigned
int, unsigned
int> &),
5502 void (CLASS::*inner_face_operation)(
5506 const
std::pair<unsigned
int, unsigned
int> &),
5507 void (CLASS::*boundary_face_operation)(
5511 const
std::pair<unsigned
int, unsigned
int> &),
5512 const CLASS *owning_class,
5514 const InVector &src,
5515 const
std::function<void(const unsigned
int, const unsigned
int)>
5516 &operation_before_loop,
5517 const
std::function<void(const unsigned
int, const unsigned
int)>
5518 &operation_after_loop,
5519 const unsigned
int dof_handler_index_pre_post,
5520 const DataAccessOnFaces dst_vector_face_access,
5521 const DataAccessOnFaces src_vector_face_access) const
5523 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5534 inner_face_operation,
5535 boundary_face_operation,
5536 src_vector_face_access,
5537 dst_vector_face_access,
5538 operation_before_loop,
5539 operation_after_loop,
5540 dof_handler_index_pre_post);
5546template <
int dim,
typename Number,
typename VectorizedArrayType>
5547template <
typename CLASS,
typename OutVector,
typename InVector>
5550 void (CLASS::*function_pointer)(
5551 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5554 const
std::pair<unsigned
int, unsigned
int> &) const,
5555 const CLASS *owning_class,
5557 const InVector &src,
5558 const
bool zero_dst_vector,
5559 const DataAccessOnFaces src_vector_face_access) const
5561 auto src_vector_face_access_temp = src_vector_face_access;
5567 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5580 src_vector_face_access_temp,
5587template <
int dim,
typename Number,
typename VectorizedArrayType>
5588template <
typename CLASS,
typename OutVector,
typename InVector>
5591 void (CLASS::*function_pointer)(
5592 const
MatrixFree<dim, Number, VectorizedArrayType> &,
5595 const
std::pair<unsigned
int, unsigned
int> &),
5596 CLASS *owning_class,
5598 const InVector &src,
5599 const
bool zero_dst_vector,
5600 const DataAccessOnFaces src_vector_face_access) const
5602 auto src_vector_face_access_temp = src_vector_face_access;
5608 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5621 src_vector_face_access_temp,
5628template <
int dim,
typename Number,
typename VectorizedArrayType>
5629template <
typename OutVector,
typename InVector>
5635 const std::pair<unsigned int, unsigned int> &)>
5638 const InVector &src,
5639 const bool zero_dst_vector,
5640 const DataAccessOnFaces src_vector_face_access)
const
5642 auto src_vector_face_access_temp = src_vector_face_access;
5643 if (DataAccessOnFaces::gradients == src_vector_face_access_temp)
5644 src_vector_face_access_temp = DataAccessOnFaces::gradients_all_faces;
5645 else if (DataAccessOnFaces::values == src_vector_face_access_temp)
5646 src_vector_face_access_temp = DataAccessOnFaces::values_all_faces;
5649 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5652 Wrapper wrap(cell_operation,
nullptr,
nullptr);
5654 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5664 &Wrapper::cell_integrator,
5665 &Wrapper::face_integrator,
5666 &Wrapper::boundary_integrator,
5667 src_vector_face_access_temp,
5668 DataAccessOnFaces::none);
5669 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
std::vector< ObserverPointer< const DoFHandler< dim > > > dof_handlers
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
unsigned int first_hp_dof_handler_index
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
std::vector< ObserverPointer< const AffineConstraints< Number > > > affine_constraints
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
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)
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.
#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.
std::vector< index_type > data
Tpetra::Vector< Number, LO, GO, NodeType< MemorySpace > > VectorType
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 > &)
unsigned short int fe_index
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