16 #ifndef dealii_quadrature_point_data_h
17 #define dealii_quadrature_point_data_h
19 #include <deal.II/base/config.h>
21 #include <deal.II/base/quadrature.h>
22 #include <deal.II/base/subscriptor.h>
24 #include <deal.II/distributed/tria.h>
26 #include <deal.II/fe/fe.h>
27 #include <deal.II/fe/fe_tools.h>
29 #include <deal.II/grid/tria.h>
30 #include <deal.II/grid/tria_accessor.h>
32 #include <deal.II/lac/vector.h>
35 #include <type_traits>
38 DEAL_II_NAMESPACE_OPEN
58 template <
typename CellIteratorType,
typename DataType>
93 template <
typename T = DataType>
96 const unsigned int number_of_data_points_per_cell);
103 template <
typename T = DataType>
105 initialize(
const CellIteratorType &cell_start,
106 const CellIteratorType &cell_end,
107 const unsigned int number_of_data_points_per_cell);
119 erase(
const CellIteratorType &cell);
138 template <
typename T = DataType>
139 std::vector<std::shared_ptr<T>>
140 get_data(
const CellIteratorType &cell);
153 template <
typename T = DataType>
154 std::vector<std::shared_ptr<const T>>
155 get_data(
const CellIteratorType &cell)
const;
161 std::map<CellIteratorType, std::vector<std::shared_ptr<DataType>>>
map;
215 pack_values(std::vector<double> &values)
const = 0;
230 #ifdef DEAL_II_WITH_P4EST
233 namespace distributed
346 template <
int dim,
typename DataType>
351 std::is_base_of<TransferableQuadraturePointData, DataType>::value,
352 "User's DataType class should be derived from TransferableQuadraturePointData");
412 const typename parallel::distributed::Triangulation<dim>::CellStatus
424 const typename parallel::distributed::Triangulation<dim>::CellStatus
426 const boost::iterator_range<std::vector<char>::const_iterator>
510 template <
typename CellIteratorType,
typename DataType>
511 template <
typename T>
514 const CellIteratorType &cell,
515 const unsigned int n_q_points)
517 static_assert(std::is_base_of<DataType, T>::value,
518 "User's T class should be derived from user's DataType class");
520 if (map.find(cell) == map.end())
522 map[cell] = std::vector<std::shared_ptr<DataType>>(n_q_points);
526 auto it = map.find(cell);
527 for (
unsigned int q = 0; q < n_q_points; q++)
528 it->second[q] = std::make_shared<T>();
534 template <
typename CellIteratorType,
typename DataType>
535 template <
typename T>
538 const CellIteratorType &cell_start,
539 const CellIteratorType &cell_end,
540 const unsigned int number)
542 for (CellIteratorType it = cell_start; it != cell_end; it++)
543 if (it->is_locally_owned())
544 initialize<T>(it, number);
549 template <
typename CellIteratorType,
typename DataType>
553 const auto it = map.find(cell);
554 for (
unsigned int i = 0; i < it->second.size(); i++)
557 it->second[i].unique(),
559 "Can not erase the cell data multiple objects reference its data."));
562 return (map.erase(cell) == 1);
567 template <
typename CellIteratorType,
typename DataType>
574 auto it = map.begin();
575 while (it != map.end())
578 for (
unsigned int i = 0; i < it->second.size(); i++)
581 it->second[i].unique(),
583 "Can not erase the cell data, multiple objects reference it."));
591 template <
typename CellIteratorType,
typename DataType>
592 template <
typename T>
593 std::vector<std::shared_ptr<T>>
595 const CellIteratorType &cell)
597 static_assert(std::is_base_of<DataType, T>::value,
598 "User's T class should be derived from user's DataType class");
600 auto it = map.find(cell);
608 std::vector<std::shared_ptr<T>> res(it->second.size());
609 for (
unsigned int q = 0; q < res.size(); q++)
610 res[q] = std::dynamic_pointer_cast<T>(it->second[q]);
616 template <
typename CellIteratorType,
typename DataType>
617 template <
typename T>
618 std::vector<std::shared_ptr<const T>>
620 const CellIteratorType &cell)
const
622 static_assert(std::is_base_of<DataType, T>::value,
623 "User's T class should be derived from user's DataType class");
625 auto it = map.find(cell);
631 std::vector<std::shared_ptr<const T>> res(it->second.size());
632 for (
unsigned int q = 0; q < res.size(); q++)
633 res[q] = std::dynamic_pointer_cast<const T>(it->second[q]);
649 template <
typename CellIteratorType,
typename DataType>
651 pack_cell_data(
const CellIteratorType & cell,
656 std::is_base_of<TransferableQuadraturePointData, DataType>::value,
657 "User's DataType class should be derived from QPData");
659 const std::vector<std::shared_ptr<const DataType>> qpd =
662 const unsigned int n = matrix_data.
n();
664 std::vector<double> single_qp_data(n);
665 Assert(qpd.size() == matrix_data.
m(),
667 for (
unsigned int q = 0; q < qpd.size(); q++)
669 qpd[q]->pack_values(single_qp_data);
670 Assert(single_qp_data.size() == n,
673 for (
unsigned int i = 0; i < n; i++)
674 matrix_data(q, i) = single_qp_data[i];
683 template <
typename CellIteratorType,
typename DataType>
685 unpack_to_cell_data(
const CellIteratorType & cell,
690 std::is_base_of<TransferableQuadraturePointData, DataType>::value,
691 "User's DataType class should be derived from QPData");
693 std::vector<std::shared_ptr<DataType>> qpd = data_storage->
get_data(cell);
695 const unsigned int n = values_at_qp.
n();
697 std::vector<double> single_qp_data(n);
698 Assert(qpd.size() == values_at_qp.
m(),
701 for (
unsigned int q = 0; q < qpd.size(); q++)
703 for (
unsigned int i = 0; i < n; i++)
704 single_qp_data[i] = values_at_qp(q, i);
705 qpd[q]->unpack_values(single_qp_data);
710 # ifdef DEAL_II_WITH_P4EST
714 namespace distributed
716 template <
int dim,
typename DataType>
722 std::unique_ptr<const
FiniteElement<dim>>(projection_fe_.clone()))
723 , data_size_in_bytes(0)
724 , n_q_points(rhs_quadrature.size())
725 , project_to_fe_matrix(projection_fe->dofs_per_cell, n_q_points)
726 , project_to_qp_matrix(n_q_points, projection_fe->dofs_per_cell)
727 , handle(
numbers::invalid_unsigned_int)
728 , data_storage(nullptr)
729 , triangulation(nullptr)
734 "ContinuousQuadratureDataTransfer requires scalar FiniteElement"));
748 template <
int dim,
typename DataType>
755 Assert(data_storage ==
nullptr,
756 ExcMessage(
"This function can be called only once"));
757 triangulation = &tr_;
758 data_storage = &data_storage_;
760 unsigned int number_of_values = 0;
765 dim>::active_cell_iterator it = triangulation->begin_active();
766 it != triangulation->end();
768 if (it->is_locally_owned())
770 std::vector<std::shared_ptr<DataType>> qpd =
772 number_of_values = qpd[0]->number_of_values();
778 triangulation->get_communicator());
780 const unsigned int dofs_per_cell = projection_fe->dofs_per_cell;
781 matrix_dofs.reinit(dofs_per_cell, number_of_values);
782 matrix_dofs_child.reinit(dofs_per_cell, number_of_values);
783 matrix_quadrature.reinit(n_q_points, number_of_values);
785 handle = triangulation->register_data_attach(
789 std::placeholders::_1,
790 std::placeholders::_2),
796 template <
int dim,
typename DataType>
800 triangulation->notify_ready_to_unpack(
805 std::placeholders::_1,
806 std::placeholders::_2,
807 std::placeholders::_3));
810 data_storage =
nullptr;
811 triangulation =
nullptr;
816 template <
int dim,
typename DataType>
824 pack_cell_data(cell, data_storage, matrix_quadrature);
827 project_to_fe_matrix.mmult(matrix_dofs, matrix_quadrature);
836 template <
int dim,
typename DataType>
841 const typename parallel::distributed::Triangulation<dim>::CellStatus
843 const boost::iterator_range<std::vector<char>::const_iterator>
852 Utilities::unpack<FullMatrix<double>>(data_range.begin(),
856 if (cell->has_children())
860 for (
unsigned int child = 0; child < cell->n_children(); ++child)
861 if (cell->child(child)->is_locally_owned())
864 ->get_prolongation_matrix(child, cell->refinement_case())
865 .mmult(matrix_dofs_child, matrix_dofs);
869 project_to_qp_matrix.mmult(matrix_quadrature,
873 unpack_to_cell_data(cell->child(child),
882 project_to_qp_matrix.mmult(matrix_quadrature, matrix_dofs);
885 unpack_to_cell_data(cell, matrix_quadrature, data_storage);
893 # endif // DEAL_II_WITH_P4EST
896 DEAL_II_NAMESPACE_CLOSE