17#ifndef dealii_matrix_free_h
18#define dealii_matrix_free_h
112 typename Number = double,
117 std::is_same<Number, typename VectorizedArrayType::value_type>::value,
118 "Type of Number and of VectorizedArrayType do not match.");
576 template <
typename QuadratureType,
typename number2,
typename MappingType>
581 const QuadratureType & quad,
590 template <
typename QuadratureType,
typename number2>
594 const QuadratureType & quad,
618 template <
typename QuadratureType,
typename number2,
typename MappingType>
623 const std::vector<QuadratureType> & quad,
631 template <
typename QuadratureType,
633 typename DoFHandlerType,
634 typename MappingType>
637 const std::vector<const DoFHandlerType *> & dof_handler,
639 const std::vector<QuadratureType> & quad,
648 template <
typename QuadratureType,
typename number2>
652 const std::vector<QuadratureType> & quad,
660 template <
typename QuadratureType,
typename number2,
typename DoFHandlerType>
662 reinit(
const std::vector<const DoFHandlerType *> & dof_handler,
664 const std::vector<QuadratureType> & quad,
674 template <
typename QuadratureType,
typename number2,
typename MappingType>
679 const QuadratureType & quad,
687 template <
typename QuadratureType,
689 typename DoFHandlerType,
690 typename MappingType>
693 const std::vector<const DoFHandlerType *> & dof_handler,
695 const QuadratureType & quad,
704 template <
typename QuadratureType,
typename number2>
708 const QuadratureType & quad,
716 template <
typename QuadratureType,
typename number2,
typename DoFHandlerType>
718 reinit(
const std::vector<const DoFHandlerType *> & dof_handler,
720 const QuadratureType & quad,
877 template <
typename OutVector,
typename InVector>
883 const std::pair<unsigned int, unsigned int> &)> &cell_operation,
885 const InVector & src,
886 const bool zero_dst_vector =
false)
const;
934 template <
typename CLASS,
typename OutVector,
typename InVector>
940 const std::pair<unsigned int, unsigned int> &)
const,
941 const CLASS * owning_class,
944 const bool zero_dst_vector =
false)
const;
949 template <
typename CLASS,
typename OutVector,
typename InVector>
955 const std::pair<unsigned int, unsigned int> &),
956 CLASS * owning_class,
959 const bool zero_dst_vector =
false)
const;
1045 template <
typename CLASS,
typename OutVector,
typename InVector>
1051 const std::pair<unsigned int, unsigned int> &)
const,
1052 const CLASS * owning_class,
1054 const InVector &src,
1055 const std::function<
void(
const unsigned int,
const unsigned int)>
1056 &operation_before_loop,
1057 const std::function<
void(
const unsigned int,
const unsigned int)>
1058 & operation_after_loop,
1059 const unsigned int dof_handler_index_pre_post = 0)
const;
1064 template <
typename CLASS,
typename OutVector,
typename InVector>
1070 const std::pair<unsigned int, unsigned int> &),
1071 CLASS * owning_class,
1073 const InVector &src,
1074 const std::function<
void(
const unsigned int,
const unsigned int)>
1075 &operation_before_loop,
1076 const std::function<
void(
const unsigned int,
const unsigned int)>
1077 & operation_after_loop,
1078 const unsigned int dof_handler_index_pre_post = 0)
const;
1084 template <
typename OutVector,
typename InVector>
1090 const std::pair<unsigned int, unsigned int> &)> &cell_operation,
1092 const InVector & src,
1093 const std::function<
void(
const unsigned int,
const unsigned int)>
1094 &operation_before_loop,
1095 const std::function<
void(
const unsigned int,
const unsigned int)>
1096 & operation_after_loop,
1097 const unsigned int dof_handler_index_pre_post = 0)
const;
1174 template <
typename OutVector,
typename InVector>
1180 const std::pair<unsigned int, unsigned int> &)> &cell_operation,
1181 const std::function<
1185 const std::pair<unsigned int, unsigned int> &)> &face_operation,
1186 const std::function<
void(
1190 const std::pair<unsigned int, unsigned int> &)> &boundary_operation,
1192 const InVector & src,
1193 const bool zero_dst_vector =
false,
1284 template <
typename CLASS,
typename OutVector,
typename InVector>
1287 void (CLASS::*cell_operation)(
const MatrixFree &,
1290 const std::pair<unsigned int, unsigned int> &)
1292 void (CLASS::*face_operation)(
const MatrixFree &,
1295 const std::pair<unsigned int, unsigned int> &)
1297 void (CLASS::*boundary_operation)(
1301 const std::pair<unsigned int, unsigned int> &)
const,
1302 const CLASS * owning_class,
1304 const InVector & src,
1305 const bool zero_dst_vector =
false,
1314 template <
typename CLASS,
typename OutVector,
typename InVector>
1316 loop(
void (CLASS::*cell_operation)(
1320 const std::pair<unsigned int, unsigned int> &),
1321 void (CLASS::*face_operation)(
1325 const std::pair<unsigned int, unsigned int> &),
1326 void (CLASS::*boundary_operation)(
1330 const std::pair<unsigned int, unsigned int> &),
1331 CLASS * owning_class,
1333 const InVector & src,
1334 const bool zero_dst_vector =
false,
1404 template <
typename CLASS,
typename OutVector,
typename InVector>
1410 const std::pair<unsigned int, unsigned int> &)
const,
1411 const CLASS * owning_class,
1413 const InVector & src,
1414 const bool zero_dst_vector =
false,
1421 template <
typename CLASS,
typename OutVector,
typename InVector>
1427 const std::pair<unsigned int, unsigned int> &),
1428 CLASS * owning_class,
1430 const InVector & src,
1431 const bool zero_dst_vector =
false,
1438 template <
typename OutVector,
typename InVector>
1444 const std::pair<unsigned int, unsigned int> &)>
1447 const InVector & src,
1448 const bool zero_dst_vector =
false,
1459 std::pair<unsigned int, unsigned int>
1461 const unsigned int fe_degree,
1462 const unsigned int dof_handler_index = 0)
const;
1470 std::pair<unsigned int, unsigned int>
1472 const std::pair<unsigned int, unsigned int> &range,
1473 const unsigned int fe_index,
1474 const unsigned int dof_handler_index = 0)
const;
1487 const std::pair<unsigned int, unsigned int> range)
const;
1494 const bool is_interior_face =
true)
const;
1507 template <
typename T>
1516 template <
typename T>
1533 template <
typename VectorType>
1536 const unsigned int dof_handler_index = 0)
const;
1555 template <
typename Number2>
1558 const unsigned int dof_handler_index = 0)
const;
1570 const std::shared_ptr<const Utilities::MPI::Partitioner> &
1594 const std::vector<unsigned int> &
1609 const unsigned int dof_handler_index = 0);
1620 template <
int spacedim>
1721 const unsigned int face_number)
const;
1740 template <
typename DoFHandlerType>
1758 const unsigned int lane_index,
1759 const unsigned int dof_handler_index = 0)
const;
1768 const unsigned int lane_index)
const;
1782 std::pair<typename DoFHandler<dim>::cell_iterator,
unsigned int>
1784 const unsigned int lane_index,
1785 const bool interior =
true,
1786 const unsigned int fe_component = 0)
const;
1795 const unsigned int lane_index,
1796 const unsigned int dof_handler_index = 0)
const;
1848 const unsigned int hp_active_fe_index = 0)
const;
1855 const unsigned int hp_active_fe_index = 0)
const;
1863 const unsigned int hp_active_fe_index = 0)
const;
1871 const unsigned int hp_active_fe_index = 0)
const;
1878 const unsigned int hp_active_fe_index = 0)
const;
1885 const unsigned int hp_active_fe_index = 0)
const;
1901 const std::pair<unsigned int, unsigned int> cell_batch_range)
const;
1907 std::pair<unsigned int, unsigned int>
1909 const std::pair<unsigned int, unsigned int> face_batch_range)
const;
1929 std::pair<unsigned int, unsigned int>
1963 template <
typename StreamType>
1991 const internal::MatrixFreeFunctions::
1992 MappingInfo<dim, Number, VectorizedArrayType> &
2027 const unsigned int quad_index = 0,
2028 const unsigned int fe_base_element = 0,
2029 const unsigned int hp_active_fe_index = 0,
2030 const unsigned int hp_active_quad_index = 0)
const;
2036 VectorizedArrayType::size()> &
2096 template <
typename number2,
int q_dim>
2102 const std::vector<IndexSet> & locally_owned_set,
2112 template <
typename number2>
2116 const std::vector<IndexSet> & locally_owned_set,
2136 std::vector<internal::MatrixFreeFunctions::DoFInfo>
dof_info;
2214 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>>
2221 mutable std::list<std::pair<bool, AlignedVector<Number>>>
2238template <
int dim,
typename Number,
typename VectorizedArrayType>
2239template <
typename T>
2244 vec.
resize(this->n_cell_batches() + this->n_ghost_cell_batches());
2249template <
int dim,
typename Number,
typename VectorizedArrayType>
2250template <
typename T>
2255 vec.
resize(this->n_inner_face_batches() + this->n_boundary_face_batches() +
2256 this->n_ghost_inner_face_batches());
2261template <
int dim,
typename Number,
typename VectorizedArrayType>
2262template <
typename VectorType>
2266 const unsigned int comp)
const
2269 "This function is not supported for block vectors.");
2271 Assert(task_info.n_procs == 1,
2272 ExcMessage(
"This function can only be used in serial."));
2275 vec.reinit(dof_info[comp].vector_partitioner->size());
2280template <
int dim,
typename Number,
typename VectorizedArrayType>
2281template <
typename Number2>
2285 const unsigned int comp)
const
2288 vec.
reinit(dof_info[comp].vector_partitioner, task_info.communicator_sm);
2293template <
int dim,
typename Number,
typename VectorizedArrayType>
2294inline const std::shared_ptr<const Utilities::MPI::Partitioner> &
2296 const unsigned int comp)
const
2299 return dof_info[comp].vector_partitioner;
2304template <
int dim,
typename Number,
typename VectorizedArrayType>
2305inline const std::vector<unsigned int> &
2307 const unsigned int comp)
const
2310 return dof_info[comp].constrained_dofs;
2315template <
int dim,
typename Number,
typename VectorizedArrayType>
2320 return dof_handlers.size();
2325template <
int dim,
typename Number,
typename VectorizedArrayType>
2328 const unsigned int dof_no)
const
2332 return dof_handlers[dof_no]->get_fe().n_base_elements();
2337template <
int dim,
typename Number,
typename VectorizedArrayType>
2346template <
int dim,
typename Number,
typename VectorizedArrayType>
2350 return *(task_info.cell_partition_data.end() - 2);
2355template <
int dim,
typename Number,
typename VectorizedArrayType>
2359 return task_info.n_active_cells;
2364template <
int dim,
typename Number,
typename VectorizedArrayType>
2368 return *(task_info.cell_partition_data.end() - 2);
2373template <
int dim,
typename Number,
typename VectorizedArrayType>
2377 return *(task_info.cell_partition_data.end() - 1) -
2378 *(task_info.cell_partition_data.end() - 2);
2383template <
int dim,
typename Number,
typename VectorizedArrayType>
2387 if (task_info.face_partition_data.size() == 0)
2389 return task_info.face_partition_data.back();
2394template <
int dim,
typename Number,
typename VectorizedArrayType>
2398 if (task_info.face_partition_data.size() == 0)
2400 return task_info.boundary_partition_data.back() -
2401 task_info.face_partition_data.back();
2406template <
int dim,
typename Number,
typename VectorizedArrayType>
2410 if (task_info.face_partition_data.size() == 0)
2412 return face_info.faces.size() - task_info.boundary_partition_data.back();
2417template <
int dim,
typename Number,
typename VectorizedArrayType>
2420 const unsigned int face_batch_index)
const
2422 Assert(face_batch_index >= task_info.boundary_partition_data[0] &&
2423 face_batch_index < task_info.boundary_partition_data.back(),
2425 task_info.boundary_partition_data[0],
2426 task_info.boundary_partition_data.back()));
2432template <
int dim,
typename Number,
typename VectorizedArrayType>
2435 const unsigned int cell_batch_index,
2436 const unsigned int face_number)
const
2440 Assert(face_info.cell_and_face_boundary_id.size(0) >= n_cell_batches(),
2444 for (
unsigned int v = 0;
2445 v < n_active_entries_per_cell_batch(cell_batch_index);
2448 face_info.cell_and_face_boundary_id(cell_batch_index, face_number, v);
2454template <
int dim,
typename Number,
typename VectorizedArrayType>
2455inline const internal::MatrixFreeFunctions::
2456 MappingInfo<dim, Number, VectorizedArrayType> &
2459 return mapping_info;
2464template <
int dim,
typename Number,
typename VectorizedArrayType>
2467 const unsigned int dof_index)
const
2470 return dof_info[dof_index];
2475template <
int dim,
typename Number,
typename VectorizedArrayType>
2479 return constraint_pool_row_index.size() - 1;
2484template <
int dim,
typename Number,
typename VectorizedArrayType>
2485inline const Number *
2487 const unsigned int row)
const
2490 return constraint_pool_data.empty() ?
2492 constraint_pool_data.data() + constraint_pool_row_index[row];
2497template <
int dim,
typename Number,
typename VectorizedArrayType>
2498inline const Number *
2500 const unsigned int row)
const
2503 return constraint_pool_data.empty() ?
2505 constraint_pool_data.data() + constraint_pool_row_index[row + 1];
2510template <
int dim,
typename Number,
typename VectorizedArrayType>
2511inline std::pair<unsigned int, unsigned int>
2513 const std::pair<unsigned int, unsigned int> &range,
2514 const unsigned int degree,
2515 const unsigned int dof_handler_component)
const
2517 if (dof_info[dof_handler_component].cell_active_fe_index.empty())
2520 dof_info[dof_handler_component].fe_index_conversion.size(), 1);
2522 dof_info[dof_handler_component].fe_index_conversion[0].size(), 1);
2523 if (dof_info[dof_handler_component].fe_index_conversion[0][0] == degree)
2526 return {range.second, range.second};
2529 const unsigned int fe_index =
2530 dof_info[dof_handler_component].fe_index_from_degree(0, degree);
2531 if (fe_index >= dof_info[dof_handler_component].max_fe_index)
2532 return {range.second, range.second};
2534 return create_cell_subrange_hp_by_index(range,
2536 dof_handler_component);
2541template <
int dim,
typename Number,
typename VectorizedArrayType>
2544 const unsigned int cell_batch_index)
const
2547 return VectorizedArrayType::size() > 1 &&
2548 cell_level_index[(cell_batch_index + 1) * VectorizedArrayType::size() -
2549 1] == cell_level_index[(cell_batch_index + 1) *
2550 VectorizedArrayType::size() -
2556template <
int dim,
typename Number,
typename VectorizedArrayType>
2560 return shape_info.size(2);
2564template <
int dim,
typename Number,
typename VectorizedArrayType>
2567 const std::pair<unsigned int, unsigned int> range)
const
2569 const auto &fe_indices = dof_info[0].cell_active_fe_index;
2571 if (fe_indices.empty() ==
true)
2574 const auto index = fe_indices[range.first];
2576 for (
unsigned int i = range.first; i < range.second; ++i)
2584template <
int dim,
typename Number,
typename VectorizedArrayType>
2587 const std::pair<unsigned int, unsigned int> range,
2588 const bool is_interior_face)
const
2590 const auto &fe_indices = dof_info[0].cell_active_fe_index;
2592 if (fe_indices.empty() ==
true)
2595 if (is_interior_face)
2597 const unsigned int index =
2598 fe_indices[face_info.faces[range.first].cells_interior[0] /
2599 VectorizedArrayType::size()];
2601 for (
unsigned int i = range.first; i < range.second; ++i)
2603 fe_indices[face_info.faces[i].cells_interior[0] /
2604 VectorizedArrayType::size()]);
2610 const unsigned int index =
2611 fe_indices[face_info.faces[range.first].cells_exterior[0] /
2612 VectorizedArrayType::size()];
2614 for (
unsigned int i = range.first; i < range.second; ++i)
2616 fe_indices[face_info.faces[i].cells_exterior[0] /
2617 VectorizedArrayType::size()]);
2625template <
int dim,
typename Number,
typename VectorizedArrayType>
2628 const unsigned int cell_batch_index)
const
2630 return n_active_entries_per_cell_batch(cell_batch_index);
2635template <
int dim,
typename Number,
typename VectorizedArrayType>
2638 const unsigned int cell_batch_index)
const
2642 const std::vector<unsigned char> &n_lanes_filled =
2643 dof_info[0].n_vectorization_lanes_filled
2647 return n_lanes_filled[cell_batch_index];
2652template <
int dim,
typename Number,
typename VectorizedArrayType>
2655 const unsigned int face_batch_index)
const
2659 const std::vector<unsigned char> &n_lanes_filled =
2660 dof_info[0].n_vectorization_lanes_filled
2663 return n_lanes_filled[face_batch_index];
2668template <
int dim,
typename Number,
typename VectorizedArrayType>
2671 const unsigned int dof_handler_index,
2672 const unsigned int active_fe_index)
const
2674 return dof_info[dof_handler_index].dofs_per_cell[active_fe_index];
2679template <
int dim,
typename Number,
typename VectorizedArrayType>
2682 const unsigned int quad_index,
2683 const unsigned int active_fe_index)
const
2686 return mapping_info.cell_data[quad_index]
2687 .descriptor[active_fe_index]
2693template <
int dim,
typename Number,
typename VectorizedArrayType>
2696 const unsigned int dof_handler_index,
2697 const unsigned int active_fe_index)
const
2699 return dof_info[dof_handler_index].dofs_per_face[active_fe_index];
2704template <
int dim,
typename Number,
typename VectorizedArrayType>
2707 const unsigned int quad_index,
2708 const unsigned int active_fe_index)
const
2711 return mapping_info.face_data[quad_index]
2712 .descriptor[active_fe_index]
2718template <
int dim,
typename Number,
typename VectorizedArrayType>
2721 const unsigned int dof_handler_index)
const
2723 return dof_info[dof_handler_index].vector_partitioner->locally_owned_range();
2728template <
int dim,
typename Number,
typename VectorizedArrayType>
2731 const unsigned int dof_handler_index)
const
2733 return dof_info[dof_handler_index].vector_partitioner->ghost_indices();
2738template <
int dim,
typename Number,
typename VectorizedArrayType>
2741 const unsigned int dof_handler_index,
2742 const unsigned int index_quad,
2743 const unsigned int index_fe,
2744 const unsigned int active_fe_index,
2745 const unsigned int active_quad_index)
const
2748 const unsigned int ind =
2749 dof_info[dof_handler_index].global_base_element_offset + index_fe;
2754 return shape_info(ind, index_quad, active_fe_index, active_quad_index);
2759template <
int dim,
typename Number,
typename VectorizedArrayType>
2761 VectorizedArrayType::size()> &
2763 const unsigned int face_batch_index)
const
2766 return face_info.faces[face_batch_index];
2771template <
int dim,
typename Number,
typename VectorizedArrayType>
2776 return face_info.cell_and_face_to_plain_faces;
2781template <
int dim,
typename Number,
typename VectorizedArrayType>
2784 const unsigned int quad_index,
2785 const unsigned int active_fe_index)
const
2788 return mapping_info.cell_data[quad_index]
2789 .descriptor[active_fe_index]
2795template <
int dim,
typename Number,
typename VectorizedArrayType>
2798 const unsigned int quad_index,
2799 const unsigned int active_fe_index)
const
2802 return mapping_info.face_data[quad_index]
2803 .descriptor[active_fe_index]
2809template <
int dim,
typename Number,
typename VectorizedArrayType>
2812 const std::pair<unsigned int, unsigned int> range)
const
2814 auto result = get_cell_category(range.first);
2816 for (
unsigned int i = range.first; i < range.second; ++i)
2817 result =
std::max(result, get_cell_category(i));
2824template <
int dim,
typename Number,
typename VectorizedArrayType>
2825inline std::pair<unsigned int, unsigned int>
2827 const std::pair<unsigned int, unsigned int> range)
const
2829 auto result = get_face_category(range.first);
2831 for (
unsigned int i = range.first; i < range.second; ++i)
2833 result.first =
std::max(result.first, get_face_category(i).
first);
2834 result.second =
std::max(result.second, get_face_category(i).
second);
2842template <
int dim,
typename Number,
typename VectorizedArrayType>
2845 const unsigned int cell_batch_index)
const
2848 AssertIndexRange(cell_batch_index, dof_info[0].cell_active_fe_index.size());
2849 if (dof_info[0].cell_active_fe_index.empty())
2852 return dof_info[0].cell_active_fe_index[cell_batch_index];
2857template <
int dim,
typename Number,
typename VectorizedArrayType>
2858inline std::pair<unsigned int, unsigned int>
2860 const unsigned int face_batch_index)
const
2863 if (dof_info[0].cell_active_fe_index.empty())
2864 return std::make_pair(0U, 0U);
2866 std::pair<unsigned int, unsigned int> result = std::make_pair(0U, 0U);
2867 for (
unsigned int v = 0;
2868 v < VectorizedArrayType::size() &&
2869 face_info.faces[face_batch_index].cells_interior[v] !=
2874 dof_info[0].cell_active_fe_index[face_info.faces[face_batch_index]
2875 .cells_interior[v] /
2876 VectorizedArrayType::size()]);
2877 if (face_info.faces[face_batch_index].cells_exterior[0] !=
2879 for (
unsigned int v = 0;
2880 v < VectorizedArrayType::size() &&
2881 face_info.faces[face_batch_index].cells_exterior[v] !=
2886 dof_info[0].cell_active_fe_index[face_info.faces[face_batch_index]
2887 .cells_exterior[v] /
2888 VectorizedArrayType::size()]);
2896template <
int dim,
typename Number,
typename VectorizedArrayType>
2900 return indices_are_initialized;
2905template <
int dim,
typename Number,
typename VectorizedArrayType>
2909 return mapping_is_initialized;
2913template <
int dim,
typename Number,
typename VectorizedArrayType>
2922template <
int dim,
typename Number,
typename VectorizedArrayType>
2927 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>;
2928 list_type &data = scratch_pad.get();
2929 for (
typename list_type::iterator it = data.begin(); it != data.end(); ++it)
2930 if (it->first ==
false)
2936 return &data.front().second;
2941template <
int dim,
typename Number,
typename VectorizedArrayType>
2947 std::list<std::pair<bool, AlignedVector<VectorizedArrayType>>>;
2948 list_type &data = scratch_pad.get();
2949 for (
typename list_type::iterator it = data.begin(); it != data.end(); ++it)
2950 if (&it->second == scratch)
2961template <
int dim,
typename Number,
typename VectorizedArrayType>
2967 scratch_pad_non_threadsafe.
begin();
2968 it != scratch_pad_non_threadsafe.end();
2970 if (it->first ==
false)
2975 scratch_pad_non_threadsafe.push_front(
2977 return &scratch_pad_non_threadsafe.front().second;
2982template <
int dim,
typename Number,
typename VectorizedArrayType>
2989 scratch_pad_non_threadsafe.
begin();
2990 it != scratch_pad_non_threadsafe.end();
2992 if (&it->second == scratch)
3007 namespace MatrixFreeImplementation
3009 template <
int dim,
int spacedim>
3010 inline std::vector<IndexSet>
3011 extract_locally_owned_index_sets(
3012 const std::vector<const ::DoFHandler<dim, spacedim> *> &dofh,
3013 const unsigned int level)
3015 std::vector<IndexSet> locally_owned_set;
3016 locally_owned_set.reserve(dofh.size());
3017 for (
unsigned int j = 0; j < dofh.size(); ++j)
3019 locally_owned_set.push_back(dofh[j]->locally_owned_dofs());
3021 locally_owned_set.push_back(dofh[j]->locally_owned_mg_dofs(
level));
3022 return locally_owned_set;
3029template <
int dim,
typename Number,
typename VectorizedArrayType>
3030template <
typename QuadratureType,
typename number2>
3035 const QuadratureType & quad,
3039 std::vector<const DoFHandler<dim, dim> *> dof_handlers;
3040 std::vector<const AffineConstraints<number2> *> constraints;
3041 std::vector<QuadratureType> quads;
3043 dof_handlers.push_back(&dof_handler);
3044 constraints.push_back(&constraints_in);
3045 quads.push_back(quad);
3047 std::vector<IndexSet> locally_owned_sets =
3048 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3049 dof_handlers, additional_data.
mg_level);
3051 std::vector<hp::QCollection<dim>> quad_hp;
3052 quad_hp.emplace_back(quad);
3065template <
int dim,
typename Number,
typename VectorizedArrayType>
3066template <
typename QuadratureType,
typename number2,
typename MappingType>
3069 const MappingType & mapping,
3072 const QuadratureType & quad,
3076 std::vector<const DoFHandler<dim, dim> *> dof_handlers;
3077 std::vector<const AffineConstraints<number2> *> constraints;
3079 dof_handlers.push_back(&dof_handler);
3080 constraints.push_back(&constraints_in);
3082 std::vector<IndexSet> locally_owned_sets =
3083 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3084 dof_handlers, additional_data.
mg_level);
3086 std::vector<hp::QCollection<dim>> quad_hp;
3087 quad_hp.emplace_back(quad);
3099template <
int dim,
typename Number,
typename VectorizedArrayType>
3100template <
typename QuadratureType,
typename number2>
3105 const std::vector<QuadratureType> & quad,
3109 std::vector<IndexSet> locally_owned_set =
3110 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3111 dof_handler, additional_data.
mg_level);
3112 std::vector<hp::QCollection<dim>> quad_hp;
3113 for (
unsigned int q = 0; q < quad.size(); ++q)
3114 quad_hp.emplace_back(quad[q]);
3127template <
int dim,
typename Number,
typename VectorizedArrayType>
3128template <
typename QuadratureType,
3130 typename DoFHandlerType,
3131 typename MappingType>
3134 const MappingType & mapping,
3135 const std::vector<const DoFHandlerType *> & dof_handler,
3137 const std::vector<QuadratureType> & quad,
3138 const AdditionalData & additional_data)
3140 static_assert(dim == DoFHandlerType::dimension,
3141 "Dimension dim not equal to DoFHandlerType::dimension.");
3143 std::vector<const DoFHandler<dim> *> dof_handlers;
3145 for (
const auto dh : dof_handler)
3146 dof_handlers.push_back(dh);
3148 this->
reinit(mapping, dof_handlers, constraint, quad, additional_data);
3153template <
int dim,
typename Number,
typename VectorizedArrayType>
3154template <
typename QuadratureType,
typename number2>
3159 const QuadratureType & quad,
3163 std::vector<IndexSet> locally_owned_set =
3164 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3165 dof_handler, additional_data.
mg_level);
3166 std::vector<hp::QCollection<dim>> quad_hp;
3167 quad_hp.emplace_back(quad);
3180template <
int dim,
typename Number,
typename VectorizedArrayType>
3181template <
typename QuadratureType,
typename number2,
typename DoFHandlerType>
3184 const std::vector<const DoFHandlerType *> & dof_handler,
3186 const std::vector<QuadratureType> & quad,
3187 const AdditionalData & additional_data)
3189 static_assert(dim == DoFHandlerType::dimension,
3190 "Dimension dim not equal to DoFHandlerType::dimension.");
3192 std::vector<const DoFHandler<dim> *> dof_handlers;
3194 for (
const auto dh : dof_handler)
3195 dof_handlers.push_back(dh);
3197 this->
reinit(dof_handlers, constraint, quad, additional_data);
3202template <
int dim,
typename Number,
typename VectorizedArrayType>
3203template <
typename QuadratureType,
typename number2,
typename MappingType>
3206 const MappingType & mapping,
3209 const QuadratureType & quad,
3213 std::vector<IndexSet> locally_owned_set =
3214 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3215 dof_handler, additional_data.
mg_level);
3216 std::vector<hp::QCollection<dim>> quad_hp;
3217 quad_hp.emplace_back(quad);
3229template <
int dim,
typename Number,
typename VectorizedArrayType>
3230template <
typename QuadratureType,
typename number2,
typename MappingType>
3233 const MappingType & mapping,
3236 const std::vector<QuadratureType> & quad,
3240 std::vector<IndexSet> locally_owned_set =
3241 internal::MatrixFreeImplementation::extract_locally_owned_index_sets(
3242 dof_handler, additional_data.
mg_level);
3243 std::vector<hp::QCollection<dim>> quad_hp;
3244 for (
unsigned int q = 0; q < quad.size(); ++q)
3245 quad_hp.emplace_back(quad[q]);
3257template <
int dim,
typename Number,
typename VectorizedArrayType>
3258template <
typename QuadratureType,
3260 typename DoFHandlerType,
3261 typename MappingType>
3264 const MappingType & mapping,
3265 const std::vector<const DoFHandlerType *> & dof_handler,
3267 const QuadratureType & quad,
3268 const AdditionalData & additional_data)
3270 static_assert(dim == DoFHandlerType::dimension,
3271 "Dimension dim not equal to DoFHandlerType::dimension.");
3273 std::vector<const DoFHandler<dim> *> dof_handlers;
3275 for (
const auto dh : dof_handler)
3276 dof_handlers.push_back(dh);
3278 this->
reinit(mapping, dof_handlers, constraint, quad, additional_data);
3283template <
int dim,
typename Number,
typename VectorizedArrayType>
3284template <
typename QuadratureType,
typename number2,
typename DoFHandlerType>
3287 const std::vector<const DoFHandlerType *> & dof_handler,
3289 const QuadratureType & quad,
3290 const AdditionalData & additional_data)
3292 static_assert(dim == DoFHandlerType::dimension,
3293 "Dimension dim not equal to DoFHandlerType::dimension.");
3295 std::vector<const DoFHandler<dim> *> dof_handlers;
3297 for (
const auto dh : dof_handler)
3298 dof_handlers.push_back(dh);
3300 this->
reinit(dof_handlers, constraint, quad, additional_data);
3320 template <
int dim,
typename Number,
typename VectorizedArrayType>
3321 struct VectorDataExchange
3328 static constexpr unsigned int channel_shift = 20;
3337 const ::MatrixFree<dim, Number, VectorizedArrayType> &matrix_free,
3338 const typename ::MatrixFree<dim, Number, VectorizedArrayType>::
3339 DataAccessOnFaces vector_face_access,
3340 const unsigned int n_components)
3341 : matrix_free(matrix_free)
3342 , vector_face_access(
3343 matrix_free.get_task_info().face_partition_data.empty() ?
3344 ::
MatrixFree<dim, Number, VectorizedArrayType>::
3345 DataAccessOnFaces::unspecified :
3347 , ghosts_were_set(false)
3348# ifdef DEAL_II_WITH_MPI
3349 , tmp_data(n_components)
3350 , requests(n_components)
3354 if (this->vector_face_access !=
3356 DataAccessOnFaces::unspecified)
3357 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
3359 matrix_free.get_dof_info(c).vector_exchanger_face_variants.size(),
3368 ~VectorDataExchange()
3370# ifdef DEAL_II_WITH_MPI
3371 for (
unsigned int i = 0; i < tmp_data.size(); ++i)
3372 if (tmp_data[i] !=
nullptr)
3373 matrix_free.release_scratch_data_non_threadsafe(tmp_data[i]);
3383 template <
typename VectorType>
3385 find_vector_in_mf(
const VectorType &vec,
3386 const bool check_global_compatibility =
true)
const
3389 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
3390 if (vec.get_partitioner().get() ==
3391 matrix_free.get_dof_info(c).vector_partitioner.get())
3395 for (
unsigned int c = 0; c < matrix_free.n_components(); ++c)
3396 if (check_global_compatibility ?
3397 vec.get_partitioner()->is_globally_compatible(
3398 *matrix_free.get_dof_info(c).vector_partitioner) :
3399 vec.get_partitioner()->is_compatible(
3400 *matrix_free.get_dof_info(c).vector_partitioner))
3416 get_partitioner(
const unsigned int mf_component)
const
3419 .vector_exchanger_face_variants.size(),
3421 if (vector_face_access ==
3423 DataAccessOnFaces::none)
3424 return *matrix_free.get_dof_info(mf_component)
3425 .vector_exchanger_face_variants[0];
3426 else if (vector_face_access ==
3428 DataAccessOnFaces::values)
3429 return *matrix_free.get_dof_info(mf_component)
3430 .vector_exchanger_face_variants[1];
3431 else if (vector_face_access ==
3433 DataAccessOnFaces::gradients)
3434 return *matrix_free.get_dof_info(mf_component)
3435 .vector_exchanger_face_variants[2];
3436 else if (vector_face_access ==
3438 DataAccessOnFaces::values_all_faces)
3439 return *matrix_free.get_dof_info(mf_component)
3440 .vector_exchanger_face_variants[3];
3441 else if (vector_face_access ==
3443 DataAccessOnFaces::gradients_all_faces)
3444 return *matrix_free.get_dof_info(mf_component)
3445 .vector_exchanger_face_variants[4];
3447 return *matrix_free.get_dof_info(mf_component).vector_exchanger.get();
3455 template <
typename VectorType,
3456 typename std::enable_if<is_not_parallel_vector<VectorType>,
3457 VectorType>::type * =
nullptr>
3459 update_ghost_values_start(
const unsigned int ,
3460 const VectorType & )
3469 typename VectorType,
3470 typename std::enable_if<!has_update_ghost_values_start<VectorType> &&
3471 !is_not_parallel_vector<VectorType>,
3472 VectorType>::type * =
nullptr>
3474 update_ghost_values_start(
const unsigned int component_in_block_vector,
3475 const VectorType & vec)
3477 (void)component_in_block_vector;
3478 bool ghosts_set = vec.has_ghost_elements();
3480 Assert(matrix_free.get_task_info().allow_ghosted_vectors_in_loops ||
3481 ghosts_set ==
false,
3485 ghosts_were_set =
true;
3487 vec.update_ghost_values();
3498 typename VectorType,
3499 typename std::enable_if<has_update_ghost_values_start<VectorType> &&
3500 !has_exchange_on_subset<VectorType>,
3501 VectorType>::type * =
nullptr>
3503 update_ghost_values_start(
const unsigned int component_in_block_vector,
3504 const VectorType & vec)
3506 (void)component_in_block_vector;
3507 bool ghosts_set = vec.has_ghost_elements();
3509 Assert(matrix_free.get_task_info().allow_ghosted_vectors_in_loops ||
3510 ghosts_set ==
false,
3514 ghosts_were_set =
true;
3516 vec.update_ghost_values_start(component_in_block_vector + channel_shift);
3528 typename VectorType,
3529 typename std::enable_if<has_update_ghost_values_start<VectorType> &&
3530 has_exchange_on_subset<VectorType>,
3531 VectorType>::type * =
nullptr>
3533 update_ghost_values_start(
const unsigned int component_in_block_vector,
3534 const VectorType & vec)
3537 std::is_same<Number, typename VectorType::value_type>::value,
3538 "Type mismatch between VectorType and VectorDataExchange");
3539 (void)component_in_block_vector;
3540 bool ghosts_set = vec.has_ghost_elements();
3542 Assert(matrix_free.get_task_info().allow_ghosted_vectors_in_loops ||
3543 ghosts_set ==
false,
3547 ghosts_were_set =
true;
3549 if (vec.size() != 0)
3551# ifdef DEAL_II_WITH_MPI
3552 const unsigned int mf_component = find_vector_in_mf(vec);
3554 const auto &part = get_partitioner(mf_component);
3556 if (part.n_ghost_indices() == 0 && part.n_import_indices() == 0 &&
3557 part.n_import_sm_procs() == 0)
3560 tmp_data[component_in_block_vector] =
3561 matrix_free.acquire_scratch_data_non_threadsafe();
3562 tmp_data[component_in_block_vector]->resize_fast(
3563 part.n_import_indices());
3566 part.export_to_ghosted_array_start(
3567 component_in_block_vector * 2 + channel_shift,
3569 vec.shared_vector_data(),
3571 part.locally_owned_size(),
3572 matrix_free.get_dof_info(mf_component)
3573 .vector_partitioner->n_ghost_indices()),
3575 part.n_import_indices()),
3576 this->requests[component_in_block_vector]);
3588 typename VectorType,
3589 typename std::enable_if<!has_update_ghost_values_start<VectorType>,
3590 VectorType>::type * =
nullptr>
3592 update_ghost_values_finish(
const unsigned int ,
3593 const VectorType & )
3604 typename VectorType,
3605 typename std::enable_if<has_update_ghost_values_start<VectorType> &&
3606 !has_exchange_on_subset<VectorType>,
3607 VectorType>::type * =
nullptr>
3609 update_ghost_values_finish(
const unsigned int component_in_block_vector,
3610 const VectorType & vec)
3612 (void)component_in_block_vector;
3613 vec.update_ghost_values_finish();
3625 typename VectorType,
3626 typename std::enable_if<has_update_ghost_values_start<VectorType> &&
3627 has_exchange_on_subset<VectorType>,
3628 VectorType>::type * =
nullptr>
3630 update_ghost_values_finish(
const unsigned int component_in_block_vector,
3631 const VectorType & vec)
3634 std::is_same<Number, typename VectorType::value_type>::value,
3635 "Type mismatch between VectorType and VectorDataExchange");
3636 (void)component_in_block_vector;
3638 if (vec.size() != 0)
3640# ifdef DEAL_II_WITH_MPI
3644 const unsigned int mf_component = find_vector_in_mf(vec);
3646 const auto &part = get_partitioner(mf_component);
3648 if (part.n_ghost_indices() != 0 || part.n_import_indices() != 0 ||
3649 part.n_import_sm_procs() != 0)
3651 part.export_to_ghosted_array_finish(
3653 vec.shared_vector_data(),
3655 part.locally_owned_size(),
3656 matrix_free.get_dof_info(mf_component)
3657 .vector_partitioner->n_ghost_indices()),
3658 this->requests[component_in_block_vector]);
3660 matrix_free.release_scratch_data_non_threadsafe(
3661 tmp_data[component_in_block_vector]);
3662 tmp_data[component_in_block_vector] =
nullptr;
3668 vec.set_ghost_state(
true);
3676 template <
typename VectorType,
3677 typename std::enable_if<is_not_parallel_vector<VectorType>,
3678 VectorType>::type * =
nullptr>
3680 compress_start(
const unsigned int ,
3690 template <
typename VectorType,
3691 typename std::enable_if<!has_compress_start<VectorType> &&
3692 !is_not_parallel_vector<VectorType>,
3693 VectorType>::type * =
nullptr>
3695 compress_start(
const unsigned int component_in_block_vector,
3698 (void)component_in_block_vector;
3710 template <
typename VectorType,
3711 typename std::enable_if<has_compress_start<VectorType> &&
3712 !has_exchange_on_subset<VectorType>,
3713 VectorType>::type * =
nullptr>
3715 compress_start(
const unsigned int component_in_block_vector,
3718 (void)component_in_block_vector;
3720 vec.compress_start(component_in_block_vector + channel_shift);
3731 template <
typename VectorType,
3732 typename std::enable_if<has_compress_start<VectorType> &&
3733 has_exchange_on_subset<VectorType>,
3734 VectorType>::type * =
nullptr>
3736 compress_start(
const unsigned int component_in_block_vector,
3740 std::is_same<Number, typename VectorType::value_type>::value,
3741 "Type mismatch between VectorType and VectorDataExchange");
3742 (void)component_in_block_vector;
3745 if (vec.size() != 0)
3747# ifdef DEAL_II_WITH_MPI
3748 const unsigned int mf_component = find_vector_in_mf(vec);
3750 const auto &part = get_partitioner(mf_component);
3752 if (part.n_ghost_indices() == 0 && part.n_import_indices() == 0 &&
3753 part.n_import_sm_procs() == 0)
3756 tmp_data[component_in_block_vector] =
3757 matrix_free.acquire_scratch_data_non_threadsafe();
3758 tmp_data[component_in_block_vector]->resize_fast(
3759 part.n_import_indices());
3762 part.import_from_ghosted_array_start(
3764 component_in_block_vector * 2 + channel_shift,
3766 vec.shared_vector_data(),
3768 matrix_free.get_dof_info(mf_component)
3769 .vector_partitioner->n_ghost_indices()),
3771 part.n_import_indices()),
3772 this->requests[component_in_block_vector]);
3783 template <
typename VectorType,
3784 typename std::enable_if<!has_compress_start<VectorType>,
3785 VectorType>::type * =
nullptr>
3787 compress_finish(
const unsigned int ,
3798 template <
typename VectorType,
3799 typename std::enable_if<has_compress_start<VectorType> &&
3800 !has_exchange_on_subset<VectorType>,
3801 VectorType>::type * =
nullptr>
3803 compress_finish(
const unsigned int component_in_block_vector,
3806 (void)component_in_block_vector;
3818 template <
typename VectorType,
3819 typename std::enable_if<has_compress_start<VectorType> &&
3820 has_exchange_on_subset<VectorType>,
3821 VectorType>::type * =
nullptr>
3823 compress_finish(
const unsigned int component_in_block_vector,
3827 std::is_same<Number, typename VectorType::value_type>::value,
3828 "Type mismatch between VectorType and VectorDataExchange");
3829 (void)component_in_block_vector;
3830 if (vec.size() != 0)
3832# ifdef DEAL_II_WITH_MPI
3836 const unsigned int mf_component = find_vector_in_mf(vec);
3838 const auto &part = get_partitioner(mf_component);
3840 if (part.n_ghost_indices() != 0 || part.n_import_indices() != 0 ||
3841 part.n_import_sm_procs() != 0)
3843 part.import_from_ghosted_array_finish(
3846 vec.shared_vector_data(),
3848 matrix_free.get_dof_info(mf_component)
3849 .vector_partitioner->n_ghost_indices()),
3851 tmp_data[component_in_block_vector]->begin(),
3852 part.n_import_indices()),
3853 this->requests[component_in_block_vector]);
3855 matrix_free.release_scratch_data_non_threadsafe(
3856 tmp_data[component_in_block_vector]);
3857 tmp_data[component_in_block_vector] =
nullptr;
3863 MPI_Barrier(matrix_free.get_task_info().communicator_sm);
3875 template <
typename VectorType,
3876 typename std::enable_if<is_not_parallel_vector<VectorType>,
3877 VectorType>::type * =
nullptr>
3879 reset_ghost_values(
const VectorType & )
const
3888 template <
typename VectorType,
3889 typename std::enable_if<!has_exchange_on_subset<VectorType> &&
3890 !is_not_parallel_vector<VectorType>,
3891 VectorType>::type * =
nullptr>
3893 reset_ghost_values(
const VectorType &vec)
const
3895 if (ghosts_were_set ==
true)
3898 vec.zero_out_ghost_values();
3908 template <
typename VectorType,
3909 typename std::enable_if<has_exchange_on_subset<VectorType>,
3910 VectorType>::type * =
nullptr>
3912 reset_ghost_values(
const VectorType &vec)
const
3915 std::is_same<Number, typename VectorType::value_type>::value,
3916 "Type mismatch between VectorType and VectorDataExchange");
3917 if (ghosts_were_set ==
true)
3920 if (vec.size() != 0)
3922# ifdef DEAL_II_WITH_MPI
3925 const unsigned int mf_component = find_vector_in_mf(vec);
3927 const auto &part = get_partitioner(mf_component);
3929 if (part.n_ghost_indices() > 0)
3934 part.locally_owned_size(),
3935 matrix_free.get_dof_info(mf_component)
3936 .vector_partitioner->n_ghost_indices()));
3942 vec.set_ghost_state(
false);
3952 template <
typename VectorType,
3953 typename std::enable_if<has_exchange_on_subset<VectorType>,
3954 VectorType>::type * =
nullptr>
3956 zero_vector_region(
const unsigned int range_index, VectorType &vec)
const
3959 std::is_same<Number, typename VectorType::value_type>::value,
3960 "Type mismatch between VectorType and VectorDataExchange");
3965 const unsigned int mf_component = find_vector_in_mf(vec,
false);
3967 matrix_free.get_dof_info(mf_component);
3975 for (
unsigned int id =
3994 template <
typename VectorType,
3995 typename std::enable_if<!has_exchange_on_subset<VectorType>,
3996 VectorType>::type * =
nullptr,
3997 typename VectorType::value_type * =
nullptr>
3999 zero_vector_region(
const unsigned int range_index, VectorType &vec)
const
4002 vec =
typename VectorType::value_type();
4012 zero_vector_region(
const unsigned int, ...)
const
4016 "which provide VectorType::value_type"));
4021 const ::MatrixFree<dim, Number, VectorizedArrayType> &matrix_free;
4022 const typename ::MatrixFree<dim, Number, VectorizedArrayType>::
4023 DataAccessOnFaces vector_face_access;
4024 bool ghosts_were_set;
4025# ifdef DEAL_II_WITH_MPI
4026 std::vector<AlignedVector<Number> *> tmp_data;
4027 std::vector<std::vector<MPI_Request>> requests;
4031 template <
typename VectorStruct>
4033 n_components(
const VectorStruct &vec);
4035 template <
typename VectorStruct>
4037 n_components_block(
const VectorStruct &vec,
4038 std::integral_constant<bool, true>)
4040 unsigned int components = 0;
4041 for (
unsigned int bl = 0; bl < vec.n_blocks(); ++bl)
4042 components += n_components(vec.block(bl));
4046 template <
typename VectorStruct>
4048 n_components_block(
const VectorStruct &, std::integral_constant<bool, false>)
4053 template <
typename VectorStruct>
4055 n_components(
const VectorStruct &vec)
4057 return n_components_block(
4061 template <
typename VectorStruct>
4063 n_components(
const std::vector<VectorStruct> &vec)
4065 unsigned int components = 0;
4066 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4067 components += n_components_block(
4073 template <
typename VectorStruct>
4075 n_components(
const std::vector<VectorStruct *> &vec)
4077 unsigned int components = 0;
4078 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4079 components += n_components_block(
4092 template <
typename VectorStruct,
4093 typename std::enable_if<!has_communication_block_size<VectorStruct>,
4094 VectorStruct>::type * =
nullptr>
4095 constexpr unsigned int
4096 get_communication_block_size(
const VectorStruct &)
4103 template <
typename VectorStruct,
4104 typename std::enable_if<has_communication_block_size<VectorStruct>,
4105 VectorStruct>::type * =
nullptr>
4106 constexpr unsigned int
4107 get_communication_block_size(
const VectorStruct &)
4109 return VectorStruct::communication_block_size;
4124 typename VectorStruct,
4126 typename VectorizedArrayType,
4127 typename std::enable_if<IsBlockVector<VectorStruct>::value,
4128 VectorStruct>::type * =
nullptr>
4130 update_ghost_values_start(
4131 const VectorStruct & vec,
4132 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4133 const unsigned int channel = 0)
4135 if (get_communication_block_size(vec) < vec.n_blocks())
4139 exchanger.ghosts_were_set = vec.has_ghost_elements();
4140 vec.update_ghost_values();
4144 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4145 update_ghost_values_start(vec.block(i), exchanger, channel + i);
4153 typename VectorStruct,
4155 typename VectorizedArrayType,
4156 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4157 VectorStruct>::type * =
nullptr>
4159 update_ghost_values_start(
4160 const VectorStruct & vec,
4161 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4162 const unsigned int channel = 0)
4164 exchanger.update_ghost_values_start(channel, vec);
4171 typename VectorStruct,
4173 typename VectorizedArrayType>
4175 update_ghost_values_start(
4176 const std::vector<VectorStruct> & vec,
4177 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4179 unsigned int component_index = 0;
4180 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4182 update_ghost_values_start(vec[comp], exchanger, component_index);
4183 component_index += n_components(vec[comp]);
4191 typename VectorStruct,
4193 typename VectorizedArrayType>
4195 update_ghost_values_start(
4196 const std::vector<VectorStruct *> & vec,
4197 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4199 unsigned int component_index = 0;
4200 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4202 update_ghost_values_start(*vec[comp], exchanger, component_index);
4203 component_index += n_components(*vec[comp]);
4215 typename VectorStruct,
4217 typename VectorizedArrayType,
4218 typename std::enable_if<IsBlockVector<VectorStruct>::value,
4219 VectorStruct>::type * =
nullptr>
4221 update_ghost_values_finish(
4222 const VectorStruct & vec,
4223 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4224 const unsigned int channel = 0)
4226 if (get_communication_block_size(vec) < vec.n_blocks())
4232 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4233 update_ghost_values_finish(vec.block(i), exchanger, channel + i);
4240 typename VectorStruct,
4242 typename VectorizedArrayType,
4243 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4244 VectorStruct>::type * =
nullptr>
4246 update_ghost_values_finish(
4247 const VectorStruct & vec,
4248 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4249 const unsigned int channel = 0)
4251 exchanger.update_ghost_values_finish(channel, vec);
4258 typename VectorStruct,
4260 typename VectorizedArrayType>
4262 update_ghost_values_finish(
4263 const std::vector<VectorStruct> & vec,
4264 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4266 unsigned int component_index = 0;
4267 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4269 update_ghost_values_finish(vec[comp], exchanger, component_index);
4270 component_index += n_components(vec[comp]);
4278 typename VectorStruct,
4280 typename VectorizedArrayType>
4282 update_ghost_values_finish(
4283 const std::vector<VectorStruct *> & vec,
4284 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4286 unsigned int component_index = 0;
4287 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4289 update_ghost_values_finish(*vec[comp], exchanger, component_index);
4290 component_index += n_components(*vec[comp]);
4302 typename VectorStruct,
4304 typename VectorizedArrayType,
4305 typename std::enable_if<IsBlockVector<VectorStruct>::value,
4306 VectorStruct>::type * =
nullptr>
4310 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4311 const unsigned int channel = 0)
4313 if (get_communication_block_size(vec) < vec.n_blocks())
4316 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4317 compress_start(vec.block(i), exchanger, channel + i);
4324 typename VectorStruct,
4326 typename VectorizedArrayType,
4327 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4328 VectorStruct>::type * =
nullptr>
4332 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4333 const unsigned int channel = 0)
4335 exchanger.compress_start(channel, vec);
4342 typename VectorStruct,
4344 typename VectorizedArrayType>
4347 std::vector<VectorStruct> & vec,
4348 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4350 unsigned int component_index = 0;
4351 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4353 compress_start(vec[comp], exchanger, component_index);
4354 component_index += n_components(vec[comp]);
4362 typename VectorStruct,
4364 typename VectorizedArrayType>
4367 std::vector<VectorStruct *> & vec,
4368 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4370 unsigned int component_index = 0;
4371 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4373 compress_start(*vec[comp], exchanger, component_index);
4374 component_index += n_components(*vec[comp]);
4386 typename VectorStruct,
4388 typename VectorizedArrayType,
4389 typename std::enable_if<IsBlockVector<VectorStruct>::value,
4390 VectorStruct>::type * =
nullptr>
4394 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4395 const unsigned int channel = 0)
4397 if (get_communication_block_size(vec) < vec.n_blocks())
4403 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4404 compress_finish(vec.block(i), exchanger, channel + i);
4411 typename VectorStruct,
4413 typename VectorizedArrayType,
4414 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4415 VectorStruct>::type * =
nullptr>
4419 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger,
4420 const unsigned int channel = 0)
4422 exchanger.compress_finish(channel, vec);
4429 typename VectorStruct,
4431 typename VectorizedArrayType>
4434 std::vector<VectorStruct> & vec,
4435 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4437 unsigned int component_index = 0;
4438 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4440 compress_finish(vec[comp], exchanger, component_index);
4441 component_index += n_components(vec[comp]);
4449 typename VectorStruct,
4451 typename VectorizedArrayType>
4454 std::vector<VectorStruct *> & vec,
4455 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4457 unsigned int component_index = 0;
4458 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4460 compress_finish(*vec[comp], exchanger, component_index);
4461 component_index += n_components(*vec[comp]);
4477 typename VectorStruct,
4479 typename VectorizedArrayType,
4480 typename std::enable_if<IsBlockVector<VectorStruct>::value,
4481 VectorStruct>::type * =
nullptr>
4484 const VectorStruct & vec,
4485 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4488 if (exchanger.ghosts_were_set ==
true)
4491 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4492 reset_ghost_values(vec.block(i), exchanger);
4499 typename VectorStruct,
4501 typename VectorizedArrayType,
4502 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4503 VectorStruct>::type * =
nullptr>
4506 const VectorStruct & vec,
4507 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4509 exchanger.reset_ghost_values(vec);
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);
4536 typename VectorStruct,
4538 typename VectorizedArrayType>
4541 const std::vector<VectorStruct *> & vec,
4542 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4545 if (exchanger.ghosts_were_set ==
true)
4548 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4549 reset_ghost_values(*vec[comp], exchanger);
4560 typename VectorStruct,
4562 typename VectorizedArrayType,
4563 typename std::enable_if<IsBlockVector<VectorStruct>::value,
4564 VectorStruct>::type * =
nullptr>
4567 const unsigned int range_index,
4569 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4571 for (
unsigned int i = 0; i < vec.n_blocks(); ++i)
4572 exchanger.zero_vector_region(range_index, vec.block(i));
4579 typename VectorStruct,
4581 typename VectorizedArrayType,
4582 typename std::enable_if<!IsBlockVector<VectorStruct>::value,
4583 VectorStruct>::type * =
nullptr>
4586 const unsigned int range_index,
4588 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4590 exchanger.zero_vector_region(range_index, vec);
4597 typename VectorStruct,
4599 typename VectorizedArrayType>
4602 const unsigned int range_index,
4603 std::vector<VectorStruct> & vec,
4604 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4606 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4607 zero_vector_region(range_index, vec[comp], exchanger);
4614 typename VectorStruct,
4616 typename VectorizedArrayType>
4619 const unsigned int range_index,
4620 std::vector<VectorStruct *> & vec,
4621 VectorDataExchange<dim, Number, VectorizedArrayType> &exchanger)
4623 for (
unsigned int comp = 0; comp < vec.size(); ++comp)
4624 zero_vector_region(range_index, *vec[comp], exchanger);
4632 template <
typename VectorStruct1,
typename VectorStruct2>
4634 apply_operation_to_constrained_dofs(
const std::vector<unsigned int> &,
4635 const VectorStruct1 &,
4639 template <
typename Number>
4641 apply_operation_to_constrained_dofs(
4642 const std::vector<unsigned int> & constrained_dofs,
4646 for (
const unsigned int i : constrained_dofs)
4651 namespace MatrixFreeFunctions
4655 template <
typename,
typename,
typename,
typename,
bool>
4656 struct InterfaceSelector
4660 template <
typename MF,
4664 struct InterfaceSelector<MF, InVector, OutVector, Container, true>
4666 using function_type = void (Container::*)(
4670 const std::pair<unsigned int, unsigned int> &)
const;
4674 template <
typename MF,
4678 struct InterfaceSelector<MF, InVector, OutVector, Container, false>
4680 using function_type =
4681 void (Container::*)(
const MF &,
4684 const std::pair<unsigned int, unsigned int> &);
4692 template <
typename MF,
4697 class MFWorker :
public MFWorkerInterface
4701 using function_type =
typename MatrixFreeFunctions::
4702 InterfaceSelector<MF, InVector, OutVector, Container, is_constant>::
4706 MFWorker(
const MF & matrix_free,
4707 const InVector & src,
4709 const bool zero_dst_vector_setting,
4710 const Container & container,
4711 function_type cell_function,
4712 function_type face_function,
4713 function_type boundary_function,
4714 const typename MF::DataAccessOnFaces src_vector_face_access =
4715 MF::DataAccessOnFaces::none,
4716 const typename MF::DataAccessOnFaces dst_vector_face_access =
4717 MF::DataAccessOnFaces::none,
4718 const std::function<
void(
const unsigned int,
const unsigned int)>
4719 &operation_before_loop = {},
4720 const std::function<void(
const unsigned int,
const unsigned int)>
4721 & operation_after_loop = {},
4722 const unsigned int dof_handler_index_pre_post = 0)
4723 : matrix_free(matrix_free)
4724 , container(
const_cast<Container &
>(container))
4725 , cell_function(cell_function)
4726 , face_function(face_function)
4727 , boundary_function(boundary_function)
4730 , src_data_exchanger(matrix_free,
4731 src_vector_face_access,
4733 , dst_data_exchanger(matrix_free,
4734 dst_vector_face_access,
4737 , zero_dst_vector_setting(zero_dst_vector_setting &&
4738 !src_and_dst_are_same)
4739 , operation_before_loop(operation_before_loop)
4740 , operation_after_loop(operation_after_loop)
4741 , dof_handler_index_pre_post(dof_handler_index_pre_post)
4746 cell(
const std::pair<unsigned int, unsigned int> &cell_range)
override
4748 if (cell_function !=
nullptr && cell_range.second > cell_range.first)
4749 for (
unsigned int i = 0; i < matrix_free.n_active_fe_indices(); ++i)
4751 const auto cell_subrange =
4752 matrix_free.create_cell_subrange_hp_by_index(cell_range, i);
4754 if (cell_subrange.second <= cell_subrange.first)
4758 cell_function)(matrix_free, this->dst, this->src, cell_subrange);
4763 cell(
const unsigned int range_index)
override
4765 process_range(cell_function,
4766 matrix_free.get_task_info().cell_partition_data_hp_ptr,
4767 matrix_free.get_task_info().cell_partition_data_hp,
4772 face(
const unsigned int range_index)
override
4774 process_range(face_function,
4775 matrix_free.get_task_info().face_partition_data_hp_ptr,
4776 matrix_free.get_task_info().face_partition_data_hp,
4781 boundary(
const unsigned int range_index)
override
4783 process_range(boundary_function,
4784 matrix_free.get_task_info().boundary_partition_data_hp_ptr,
4785 matrix_free.get_task_info().boundary_partition_data_hp,
4791 process_range(
const function_type & fu,
4792 const std::vector<unsigned int> &ptr,
4793 const std::vector<unsigned int> &data,
4794 const unsigned int range_index)
4800 for (
unsigned int i = ptr[range_index]; i < ptr[range_index + 1]; ++i)
4803 (container.*fu)(matrix_free,
4806 std::make_pair(data[2 * i], data[2 * i + 1]));
4818 vector_update_ghosts_start()
override
4820 if (!src_and_dst_are_same)
4821 internal::update_ghost_values_start(src, src_data_exchanger);
4826 vector_update_ghosts_finish()
override
4828 if (!src_and_dst_are_same)
4829 internal::update_ghost_values_finish(src, src_data_exchanger);
4834 vector_compress_start()
override
4836 internal::compress_start(dst, dst_data_exchanger);
4841 vector_compress_finish()
override
4843 internal::compress_finish(dst, dst_data_exchanger);
4844 if (!src_and_dst_are_same)
4845 internal::reset_ghost_values(src, src_data_exchanger);
4850 zero_dst_vector_range(
const unsigned int range_index)
override
4852 if (zero_dst_vector_setting)
4853 internal::zero_vector_region(range_index, dst, dst_data_exchanger);
4857 cell_loop_pre_range(
const unsigned int range_index)
override
4859 if (operation_before_loop)
4862 matrix_free.get_dof_info(dof_handler_index_pre_post);
4869 operation_before_loop,
4876 for (
unsigned int id =
4887 cell_loop_post_range(
const unsigned int range_index)
override
4889 if (operation_after_loop)
4893 const std::vector<unsigned int> &partition_row_index =
4894 matrix_free.get_task_info().partition_row_index;
4896 partition_row_index[partition_row_index.size() - 2] - 1)
4897 apply_operation_to_constrained_dofs(
4898 matrix_free.get_constrained_dofs(dof_handler_index_pre_post),
4903 matrix_free.get_dof_info(dof_handler_index_pre_post);
4910 operation_after_loop,
4917 for (
unsigned int id =
4928 const MF & matrix_free;
4929 Container & container;
4930 function_type cell_function;
4931 function_type face_function;
4932 function_type boundary_function;
4934 const InVector &src;
4936 VectorDataExchange<MF::dimension,
4937 typename MF::value_type,
4938 typename MF::vectorized_value_type>
4940 VectorDataExchange<MF::dimension,
4941 typename MF::value_type,
4942 typename MF::vectorized_value_type>
4944 const bool src_and_dst_are_same;
4945 const bool zero_dst_vector_setting;
4946 const std::function<void(
const unsigned int,
const unsigned int)>
4947 operation_before_loop;
4948 const std::function<void(
const unsigned int,
const unsigned int)>
4949 operation_after_loop;
4950 const unsigned int dof_handler_index_pre_post;
4959 template <
class MF,
typename InVector,
typename OutVector>
4960 struct MFClassWrapper
4962 using function_type =
4963 std::function<void(
const MF &,
4966 const std::pair<unsigned int, unsigned int> &)>;
4968 MFClassWrapper(
const function_type cell,
4969 const function_type face,
4970 const function_type boundary)
4973 , boundary(boundary)
4977 cell_integrator(
const MF & mf,
4979 const InVector & src,
4980 const std::pair<unsigned int, unsigned int> &range)
const
4983 cell(mf, dst, src, range);
4987 face_integrator(
const MF & mf,
4989 const InVector & src,
4990 const std::pair<unsigned int, unsigned int> &range)
const
4993 face(mf, dst, src, range);
4997 boundary_integrator(
5000 const InVector & src,
5001 const std::pair<unsigned int, unsigned int> &range)
const
5004 boundary(mf, dst, src, range);
5007 const function_type cell;
5008 const function_type face;
5009 const function_type boundary;
5016template <
int dim,
typename Number,
typename VectorizedArrayType>
5017template <
typename OutVector,
typename InVector>
5023 const std::pair<unsigned int, unsigned int> &)>
5026 const InVector &src,
5027 const bool zero_dst_vector)
const
5030 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5033 Wrapper wrap(cell_operation,
nullptr,
nullptr);
5034 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5044 &Wrapper::cell_integrator,
5045 &Wrapper::face_integrator,
5046 &Wrapper::boundary_integrator);
5048 task_info.loop(worker);
5053template <
int dim,
typename Number,
typename VectorizedArrayType>
5054template <
typename OutVector,
typename InVector>
5060 const std::pair<unsigned int, unsigned int> &)>
5063 const InVector &src,
5064 const std::function<
void(
const unsigned int,
const unsigned int)>
5065 &operation_before_loop,
5066 const std::function<
void(
const unsigned int,
const unsigned int)>
5067 & operation_after_loop,
5068 const unsigned int dof_handler_index_pre_post)
const
5071 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5074 Wrapper wrap(cell_operation,
nullptr,
nullptr);
5075 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5085 &Wrapper::cell_integrator,
5086 &Wrapper::face_integrator,
5087 &Wrapper::boundary_integrator,
5088 DataAccessOnFaces::none,
5089 DataAccessOnFaces::none,
5090 operation_before_loop,
5091 operation_after_loop,
5092 dof_handler_index_pre_post);
5094 task_info.loop(worker);
5099template <
int dim,
typename Number,
typename VectorizedArrayType>
5100template <
typename OutVector,
typename InVector>
5106 const std::pair<unsigned int, unsigned int> &)>
5111 const std::pair<unsigned int, unsigned int> &)>
5116 const std::pair<unsigned int, unsigned int> &)>
5117 & boundary_operation,
5119 const InVector & src,
5120 const bool zero_dst_vector,
5121 const DataAccessOnFaces dst_vector_face_access,
5122 const DataAccessOnFaces src_vector_face_access)
const
5125 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5128 Wrapper wrap(cell_operation, face_operation, boundary_operation);
5129 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5139 &Wrapper::cell_integrator,
5140 &Wrapper::face_integrator,
5141 &Wrapper::boundary_integrator,
5142 src_vector_face_access,
5143 dst_vector_face_access);
5145 task_info.loop(worker);
5150template <
int dim,
typename Number,
typename VectorizedArrayType>
5151template <
typename CLASS,
typename OutVector,
typename InVector>
5154 void (CLASS::*function_pointer)(
5158 const std::pair<unsigned int, unsigned int> &)
const,
5159 const CLASS * owning_class,
5161 const InVector &src,
5162 const bool zero_dst_vector)
const
5164 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5177 task_info.loop(worker);
5182template <
int dim,
typename Number,
typename VectorizedArrayType>
5183template <
typename CLASS,
typename OutVector,
typename InVector>
5186 void (CLASS::*function_pointer)(
5190 const std::pair<unsigned int, unsigned int> &)
const,
5191 const CLASS * owning_class,
5193 const InVector &src,
5194 const std::function<
void(
const unsigned int,
const unsigned int)>
5195 &operation_before_loop,
5196 const std::function<
void(
const unsigned int,
const unsigned int)>
5197 & operation_after_loop,
5198 const unsigned int dof_handler_index_pre_post)
const
5200 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5213 DataAccessOnFaces::none,
5214 DataAccessOnFaces::none,
5215 operation_before_loop,
5216 operation_after_loop,
5217 dof_handler_index_pre_post);
5218 task_info.loop(worker);
5223template <
int dim,
typename Number,
typename VectorizedArrayType>
5224template <
typename CLASS,
typename OutVector,
typename InVector>
5227 void (CLASS::*cell_operation)(
5231 const std::pair<unsigned int, unsigned int> &)
const,
5232 void (CLASS::*face_operation)(
5236 const std::pair<unsigned int, unsigned int> &)
const,
5237 void (CLASS::*boundary_operation)(
5241 const std::pair<unsigned int, unsigned int> &)
const,
5242 const CLASS * owning_class,
5244 const InVector & src,
5245 const bool zero_dst_vector,
5246 const DataAccessOnFaces dst_vector_face_access,
5247 const DataAccessOnFaces src_vector_face_access)
const
5249 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5262 src_vector_face_access,
5263 dst_vector_face_access);
5264 task_info.loop(worker);
5269template <
int dim,
typename Number,
typename VectorizedArrayType>
5270template <
typename CLASS,
typename OutVector,
typename InVector>
5273 void (CLASS::*function_pointer)(
5277 const std::pair<unsigned int, unsigned int> &),
5278 CLASS * owning_class,
5280 const InVector &src,
5281 const bool zero_dst_vector)
const
5283 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5296 task_info.loop(worker);
5301template <
int dim,
typename Number,
typename VectorizedArrayType>
5302template <
typename CLASS,
typename OutVector,
typename InVector>
5305 void (CLASS::*function_pointer)(
5309 const std::pair<unsigned int, unsigned int> &),
5310 CLASS * owning_class,
5312 const InVector &src,
5313 const std::function<
void(
const unsigned int,
const unsigned int)>
5314 &operation_before_loop,
5315 const std::function<
void(
const unsigned int,
const unsigned int)>
5316 & operation_after_loop,
5317 const unsigned int dof_handler_index_pre_post)
const
5319 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5332 DataAccessOnFaces::none,
5333 DataAccessOnFaces::none,
5334 operation_before_loop,
5335 operation_after_loop,
5336 dof_handler_index_pre_post);
5337 task_info.loop(worker);
5342template <
int dim,
typename Number,
typename VectorizedArrayType>
5343template <
typename CLASS,
typename OutVector,
typename InVector>
5346 void (CLASS::*cell_operation)(
5350 const std::pair<unsigned int, unsigned int> &),
5351 void (CLASS::*face_operation)(
5355 const std::pair<unsigned int, unsigned int> &),
5356 void (CLASS::*boundary_operation)(
5360 const std::pair<unsigned int, unsigned int> &),
5361 CLASS * owning_class,
5363 const InVector & src,
5364 const bool zero_dst_vector,
5365 const DataAccessOnFaces dst_vector_face_access,
5366 const DataAccessOnFaces src_vector_face_access)
const
5368 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5381 src_vector_face_access,
5382 dst_vector_face_access);
5383 task_info.loop(worker);
5388template <
int dim,
typename Number,
typename VectorizedArrayType>
5389template <
typename CLASS,
typename OutVector,
typename InVector>
5392 void (CLASS::*function_pointer)(
5396 const std::pair<unsigned int, unsigned int> &)
const,
5397 const CLASS * owning_class,
5399 const InVector & src,
5400 const bool zero_dst_vector,
5401 const DataAccessOnFaces src_vector_face_access)
const
5403 auto src_vector_face_access_temp = src_vector_face_access;
5404 if (DataAccessOnFaces::gradients == src_vector_face_access_temp)
5405 src_vector_face_access_temp = DataAccessOnFaces::gradients_all_faces;
5406 else if (DataAccessOnFaces::values == src_vector_face_access_temp)
5407 src_vector_face_access_temp = DataAccessOnFaces::values_all_faces;
5409 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5422 src_vector_face_access_temp,
5423 DataAccessOnFaces::none);
5424 task_info.loop(worker);
5429template <
int dim,
typename Number,
typename VectorizedArrayType>
5430template <
typename CLASS,
typename OutVector,
typename InVector>
5433 void (CLASS::*function_pointer)(
5437 const std::pair<unsigned int, unsigned int> &),
5438 CLASS * owning_class,
5440 const InVector & src,
5441 const bool zero_dst_vector,
5442 const DataAccessOnFaces src_vector_face_access)
const
5444 auto src_vector_face_access_temp = src_vector_face_access;
5445 if (DataAccessOnFaces::gradients == src_vector_face_access_temp)
5446 src_vector_face_access_temp = DataAccessOnFaces::gradients_all_faces;
5447 else if (DataAccessOnFaces::values == src_vector_face_access_temp)
5448 src_vector_face_access_temp = DataAccessOnFaces::values_all_faces;
5450 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5463 src_vector_face_access_temp,
5464 DataAccessOnFaces::none);
5465 task_info.loop(worker);
5470template <
int dim,
typename Number,
typename VectorizedArrayType>
5471template <
typename OutVector,
typename InVector>
5477 const std::pair<unsigned int, unsigned int> &)>
5480 const InVector & src,
5481 const bool zero_dst_vector,
5482 const DataAccessOnFaces src_vector_face_access)
const
5484 auto src_vector_face_access_temp = src_vector_face_access;
5485 if (DataAccessOnFaces::gradients == src_vector_face_access_temp)
5486 src_vector_face_access_temp = DataAccessOnFaces::gradients_all_faces;
5487 else if (DataAccessOnFaces::values == src_vector_face_access_temp)
5488 src_vector_face_access_temp = DataAccessOnFaces::values_all_faces;
5491 internal::MFClassWrapper<MatrixFree<dim, Number, VectorizedArrayType>,
5494 Wrapper wrap(cell_operation,
nullptr,
nullptr);
5496 internal::MFWorker<MatrixFree<dim, Number, VectorizedArrayType>,
5506 &Wrapper::cell_integrator,
5507 &Wrapper::face_integrator,
5508 &Wrapper::boundary_integrator,
5509 src_vector_face_access_temp,
5510 DataAccessOnFaces::none);
5511 task_info.loop(worker);
void resize(const size_type new_size)
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
DoFHandler< dim >::active_cell_iterator get_hp_cell_iterator(const unsigned int cell_batch_index, const unsigned int lane_index, const unsigned int dof_handler_index=0) const
unsigned int n_ghost_cell_batches() const
void loop(const std::function< void(const MatrixFree< dim, Number, VectorizedArrayType > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &cell_operation, const std::function< void(const MatrixFree< dim, Number, VectorizedArrayType > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &face_operation, const std::function< void(const MatrixFree< dim, Number, VectorizedArrayType > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &boundary_operation, OutVector &dst, const InVector &src, const bool zero_dst_vector=false, const DataAccessOnFaces dst_vector_face_access=DataAccessOnFaces::unspecified, const DataAccessOnFaces src_vector_face_access=DataAccessOnFaces::unspecified) const
const internal::MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > & get_shape_info(const unsigned int dof_handler_index_component=0, const unsigned int quad_index=0, const unsigned int fe_base_element=0, const unsigned int hp_active_fe_index=0, const unsigned int hp_active_quad_index=0) const
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
Table< 4, internal::MatrixFreeFunctions::ShapeInfo< VectorizedArrayType > > shape_info
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
void reinit(const std::vector< const DoFHandler< dim > * > &dof_handler, const std::vector< const AffineConstraints< number2 > * > &constraint, const QuadratureType &quad, const AdditionalData &additional_data=AdditionalData())
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
unsigned int n_components_filled(const unsigned int cell_batch_number) const
void print_memory_consumption(StreamType &out) const
void reinit(const std::vector< const DoFHandlerType * > &dof_handler, const std::vector< const AffineConstraints< number2 > * > &constraint, const std::vector< QuadratureType > &quad, const AdditionalData &additional_data=AdditionalData())
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
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 DoFHandlerType & get_dof_handler(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::*face_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &) const, void(CLASS::*boundary_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
void reinit(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::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
void reinit(const MappingType &mapping, const std::vector< const DoFHandlerType * > &dof_handler, const std::vector< const AffineConstraints< number2 > * > &constraint, const QuadratureType &quad, const AdditionalData &additional_data=AdditionalData())
Threads::ThreadLocalStorage< std::list< std::pair< bool, AlignedVector< VectorizedArrayType > > > > scratch_pad
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
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 reinit(const std::vector< const DoFHandlerType * > &dof_handler, const std::vector< const AffineConstraints< number2 > * > &constraint, const QuadratureType &quad, const AdditionalData &additional_data=AdditionalData())
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())
void cell_loop(const std::function< void(const MatrixFree< dim, Number, VectorizedArrayType > &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &)> &cell_operation, OutVector &dst, const InVector &src, const bool zero_dst_vector=false) const
unsigned int n_macro_cells() const
void reinit(const MappingType &mapping, const std::vector< const DoFHandlerType * > &dof_handler, const std::vector< const AffineConstraints< number2 > * > &constraint, const std::vector< QuadratureType > &quad, const AdditionalData &additional_data=AdditionalData())
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 loop(void(CLASS::*cell_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), void(CLASS::*face_operation)(const MatrixFree &, OutVector &, const InVector &, const std::pair< unsigned int, unsigned int > &), void(CLASS::*boundary_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 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 std::vector< unsigned int > & get_constrained_dofs(const unsigned int dof_handler_index=0) const
void reinit(const DoFHandler< dim > &dof_handler, const AffineConstraints< number2 > &constraint, const QuadratureType &quad, const AdditionalData &additional_data=AdditionalData())
unsigned int cell_level_index_end_local
unsigned int n_base_elements(const unsigned int dof_handler_index) const
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_DEPRECATED
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
@ update_JxW_values
Transformed quadrature weights.
@ update_gradients
Shape function gradients.
@ update_default
No update.
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
typename ActiveSelector::active_cell_iterator active_cell_iterator
Number local_element(const size_type local_index) const
void reinit(const size_type size, const bool omit_zeroing_entries=false)
VectorType::value_type * begin(VectorType &V)
unsigned int minimum_parallel_grain_size
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
const types::boundary_id invalid_boundary_id
static const unsigned int invalid_unsigned_int
void apply_to_subranges(const RangeType &begin, const typename identity< RangeType >::type &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
static bool equal(const T *p1, const T *p2)
@ 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