46#include <boost/geometry/algorithms/distance.hpp>
47#include <boost/geometry/index/detail/rtree/utilities/print.hpp>
48#include <boost/geometry/index/rtree.hpp>
49#include <boost/geometry/strategies/strategies.hpp>
53#ifdef DEAL_II_WITH_TRILINOS
54# include <EpetraExt_RowMatrixOut.h>
57#ifdef DEAL_II_WITH_CGAL
59# include <CGAL/Constrained_Delaunay_triangulation_2.h>
60# include <CGAL/Constrained_triangulation_plus_2.h>
61# include <CGAL/Exact_predicates_exact_constructions_kernel.h>
62# include <CGAL/Exact_predicates_exact_constructions_kernel_with_sqrt.h>
63# include <CGAL/Polygon_2.h>
64# include <CGAL/Polygon_with_holes_2.h>
65# include <CGAL/Segment_Delaunay_graph_2.h>
66# include <CGAL/Segment_Delaunay_graph_traits_2.h>
67# include <CGAL/intersections.h>
68# include <CGAL/squared_distance_2.h>
69# include <CGAL/squared_distance_3.h>
83 get_index(
const std::vector<types::global_cell_index> &v,
86 return std::distance(v.begin(), std::find(v.begin(), v.end(), index));
95 template <
int dim,
int spacedim>
101 const std::vector<types::global_cell_index> locally_owned_cells)
114 for (
const auto &cell :
triangulation.active_cell_iterators())
116 if (cell->is_locally_owned())
118 const unsigned int index = cell->active_cell_index();
119 cell_connectivity.
add(
get_index(locally_owned_cells, index),
121 for (
auto f : cell->face_indices())
122 if ((cell->at_boundary(f) ==
false) &&
123 (cell->neighbor(f)->has_children() ==
false) &&
124 cell->neighbor(f)->is_locally_owned())
126 const unsigned int other_index =
127 cell->neighbor(f)->active_cell_index();
129 cell_connectivity.
add(
get_index(locally_owned_cells, index),
144 template <
typename Value,
149 struct Rtree_visitor :
public boost::geometry::index::detail::rtree::visitor<
151 typename Options::parameters_type,
154 typename Options::node_tag,
161 boost::geometry::dimension<Box>::value>::active_cell_iterator>> &boxes,
162 std::vector<std::vector<unsigned int>> &csr);
169 typename boost::geometry::index::detail::rtree::internal_node<
171 typename Options::parameters_type,
174 typename Options::node_tag>::type;
179 using Leaf =
typename boost::geometry::index::detail::rtree::leaf<
181 typename Options::parameters_type,
184 typename Options::node_tag>::type;
228 boost::geometry::dimension<Box>::value>::active_cell_iterator>>
231 std::vector<std::vector<unsigned int>> &
row_ptr;
236 template <
typename Value,
245 boost::geometry::dimension<Box>::value>::active_cell_iterator>>
247 std::vector<std::vector<unsigned int>> &csr)
259 template <
typename Value,
268 using elements_type =
269 typename boost::geometry::index::detail::rtree::elements_type<
271 const elements_type &elements =
272 boost::geometry::index::detail::rtree::elements(node);
276 size_t level_backup =
level;
279 for (
typename elements_type::const_iterator it = elements.begin();
280 it != elements.end();
283 boost::geometry::index::detail::rtree::apply_visitor(*
this,
287 level = level_backup;
298 size_t level_backup =
level;
301 for (
const auto &child : elements)
303 boost::geometry::index::detail::rtree::apply_visitor(*
this,
310 level = level_backup;
315 size_t level_backup =
level;
319 for (
const auto &child : elements)
321 boost::geometry::index::detail::rtree::apply_visitor(*
this,
324 level = level_backup;
331 template <
typename Value,
340 using elements_type =
341 typename boost::geometry::index::detail::rtree::elements_type<
343 const elements_type &elements =
344 boost::geometry::index::detail::rtree::elements(leaf);
347 for (
const auto &it : elements)
354 template <
typename Rtree>
356 std::vector<std::vector<unsigned int>>,
357 std::vector<std::vector<
typename Triangulation<boost::geometry::dimension<
358 typename Rtree::indexable_type>::value>::active_cell_iterator>>>
362 boost::geometry::index::detail::rtree::utilities::view<Rtree>;
365 std::vector<std::vector<unsigned int>> csrs;
366 std::vector<std::vector<
typename Triangulation<boost::geometry::dimension<
367 typename Rtree::indexable_type>::value>::active_cell_iterator>>
370 if (rtv.depth() == 0)
375 agglomerates.resize(1);
376 agglomerates[0].resize(1);
382 const unsigned int target_level =
386 typename RtreeView::options_type,
387 typename RtreeView::translator_type,
388 typename RtreeView::box_type,
389 typename RtreeView::allocators_type>
390 node_visitor(rtv.translator(), target_level, agglomerates, csrs);
391 rtv.apply_visitor(node_visitor);
395 return {csrs, agglomerates};
399 template <
int dim,
typename Number =
double>
402 const unsigned int face_index,
407#ifdef DEAL_II_WITH_CGAL
409 using Kernel = CGAL::Exact_predicates_exact_constructions_kernel;
410 std::vector<typename Kernel::FT> candidates;
411 candidates.reserve(polygon_boundary.size() - 1);
415 std::vector<unsigned int> face_indices(polygon_boundary.size());
416 std::iota(face_indices.begin(), face_indices.end(), 0);
417 face_indices.erase(face_indices.cbegin() +
420 if constexpr (dim == 2)
422 typename Kernel::Segment_2 face_segm(
423 {polygon_boundary[face_index]->vertex(0)[0],
424 polygon_boundary[face_index]->vertex(0)[1]},
425 {polygon_boundary[face_index]->vertex(1)[0],
426 polygon_boundary[face_index]->vertex(1)[1]});
430 const auto &midpoint = CGAL::midpoint(face_segm);
432 const typename Kernel::Vector_2 orthogonal_direction{-deal_normal[0],
434 const typename Kernel::Ray_2 ray(midpoint, orthogonal_direction);
435 for (
const auto f : face_indices)
437 typename Kernel::Segment_2 segm({polygon_boundary[f]->vertex(0)[0],
438 polygon_boundary[f]->vertex(0)[1]},
439 {polygon_boundary[f]->vertex(1)[0],
440 polygon_boundary[f]->vertex(
443 if (CGAL::do_intersect(ray, segm))
444 candidates.push_back(CGAL::squared_distance(midpoint, segm));
447 *std::min_element(candidates.cbegin(), candidates.cend())));
449 else if constexpr (dim == 3)
451 const typename Kernel::Point_3 ¢er{
452 polygon_boundary[face_index]->center()[0],
453 polygon_boundary[face_index]->center()[1],
454 polygon_boundary[face_index]->center()[2]};
456 const typename Kernel::Vector_3 orthogonal_direction{-deal_normal[0],
459 const typename Kernel::Ray_3 ray(center, orthogonal_direction);
461 for (
const auto f : face_indices)
464 typename Kernel::Triangle_3 first_triangle(
465 {polygon_boundary[f]->vertex(0)[0],
466 polygon_boundary[f]->vertex(0)[1],
467 polygon_boundary[f]->vertex(0)[2]},
468 {polygon_boundary[f]->vertex(1)[0],
469 polygon_boundary[f]->vertex(1)[1],
470 polygon_boundary[f]->vertex(1)[2]},
471 {polygon_boundary[f]->vertex(3)[0],
472 polygon_boundary[f]->vertex(3)[1],
473 polygon_boundary[f]->vertex(3)[2]});
474 typename Kernel::Triangle_3 second_triangle(
475 {polygon_boundary[f]->vertex(0)[0],
476 polygon_boundary[f]->vertex(0)[1],
477 polygon_boundary[f]->vertex(0)[2]},
478 {polygon_boundary[f]->vertex(3)[0],
479 polygon_boundary[f]->vertex(3)[1],
480 polygon_boundary[f]->vertex(3)[2]},
481 {polygon_boundary[f]->vertex(2)[0],
482 polygon_boundary[f]->vertex(2)[1],
483 polygon_boundary[f]->vertex(2)[2]});
487 if (CGAL::do_intersect(ray, first_triangle))
488 candidates.push_back(
489 CGAL::squared_distance(center, first_triangle));
490 if (CGAL::do_intersect(ray, second_triangle))
491 candidates.push_back(
492 CGAL::squared_distance(center, second_triangle));
496 *std::min_element(candidates.cbegin(), candidates.cend())));
500 Assert(
false, ExcImpossibleInDim(dim));
502 (void)polygon_boundary;
508 Assert(
false, ExcNeedsCGAL());
510 (void)polygon_boundary;
521 template <
int dim,
int spacedim = dim>
525 const std::vector<types::global_cell_index> &cell_idxs,
527 &cells_to_be_agglomerated)
529 Assert(cells_to_be_agglomerated.size() == 0,
531 "The vector of cells is supposed to be filled by this function."));
533 if (std::find(cell_idxs.begin(),
535 cell->active_cell_index()) != cell_idxs.end())
537 cells_to_be_agglomerated.push_back(cell);
553 template <
int dim,
int spacedim>
561 ExcMessage(
"Invalid number of partitions, you provided " +
562 std::to_string(n_partitions)));
564 auto parallel_triangulation =
568 (parallel_triangulation !=
nullptr),
570 "Only fully distributed triangulations are supported. If you are using"
571 "a parallel::distributed::triangulation, you must convert it to a fully"
572 "distributed as explained in the documentation."));
575 if (n_partitions == 1)
577 for (
const auto &cell : parallel_triangulation->active_cell_iterators())
578 if (cell->is_locally_owned())
579 cell->set_material_id(0);
584 std::vector<types::global_cell_index> locally_owned_cells;
585 for (
const auto &cell :
triangulation.active_cell_iterators())
586 if (cell->is_locally_owned())
587 locally_owned_cells.push_back(cell->active_cell_index());
592 locally_owned_cells);
595 sp_cell_connectivity.
copy_from(cell_connectivity);
601 std::vector<unsigned int> partition_indices(
602 parallel_triangulation->n_locally_owned_active_cells());
610 for (
const auto &cell : parallel_triangulation->active_cell_iterators())
611 if (cell->is_locally_owned())
612 cell->set_material_id(
614 cell->active_cell_index())]);
629 template <
int dim,
int spacedim>
633 const unsigned int n_partitions,
641 "The agglomerated grid must be empty upon calling this function."));
643 ExcMessage(
"Invalid number of partitions, you provided " +
644 std::to_string(n_partitions)));
646 auto parallel_triangulation =
650 (parallel_triangulation !=
nullptr),
652 "Only fully distributed triangulations are supported. If you are using"
653 "a parallel::distributed::triangulation, you must convert it to a"
654 "fully distributed as explained in the documentation."));
657 if (n_partitions == 1)
659 for (
const auto &cell : parallel_triangulation->active_cell_iterators())
660 if (cell->is_locally_owned())
666 std::vector<types::global_cell_index> locally_owned_cells;
667 for (
const auto &cell :
triangulation.active_cell_iterators())
668 if (cell->is_locally_owned())
669 locally_owned_cells.push_back(cell->active_cell_index());
674 locally_owned_cells);
677 sp_cell_connectivity.
copy_from(cell_connectivity);
683 std::vector<unsigned int> partition_indices(
684 parallel_triangulation->n_locally_owned_active_cells());
690 std::vector<std::vector<typename Triangulation<dim>::active_cell_iterator>>
691 cells_per_partion_id;
692 cells_per_partion_id.resize(n_partitions);
695 for (
const auto &cell : parallel_triangulation->active_cell_iterators())
696 if (cell->is_locally_owned())
698 locally_owned_cells, cell->active_cell_index())]]
702 for (
unsigned int i = 0; i < n_partitions; ++i)
710 tuple<std::vector<double>, std::vector<double>, std::vector<double>,
double>
713 static_assert(dim == 2);
714#ifdef DEAL_II_WITH_CGAL
715 using Kernel = CGAL::Exact_predicates_exact_constructions_kernel_with_sqrt;
716 using Polygon_with_holes =
typename CGAL::Polygon_with_holes_2<Kernel>;
717 using Gt =
typename CGAL::Segment_Delaunay_graph_traits_2<Kernel>;
718 using SDG2 =
typename CGAL::Segment_Delaunay_graph_2<Gt>;
719 using CDT =
typename CGAL::Constrained_Delaunay_triangulation_2<Kernel>;
720 using CDTP =
typename CGAL::Constrained_triangulation_plus_2<CDT>;
721 using Point =
typename CDTP::Point;
722 using Cid =
typename CDTP::Constraint_id;
723 using Vertex_handle =
typename CDTP::Vertex_handle;
726 const auto compute_radius_inscribed_circle =
727 [](
const CGAL::Polygon_2<Kernel> &polygon) ->
double {
730 sdg.insert_segments(polygon.edges_begin(), polygon.edges_end());
732 double sd = 0, sqdist = 0;
733 typename SDG2::Finite_faces_iterator fit = sdg.finite_faces_begin();
734 for (; fit != sdg.finite_faces_end(); ++fit)
736 typename Kernel::Point_2 pp = sdg.primal(fit);
737 for (
int i = 0; i < 3; ++i)
739 assert(!sdg.is_infinite(fit->vertex(i)));
740 if (fit->vertex(i)->site().is_segment())
742 typename Kernel::Segment_2 s =
743 fit->vertex(i)->site().segment();
744 sqdist = CGAL::to_double(CGAL::squared_distance(pp, s));
748 typename Kernel::Point_2 p = fit->vertex(i)->site().point();
749 sqdist = CGAL::to_double(CGAL::squared_distance(pp, p));
753 if (polygon.bounded_side(pp) == CGAL::ON_BOUNDED_SIDE)
760 const auto mesh_size = [&ah]() ->
double {
763 if (polytope->is_locally_owned())
765 const double diameter = polytope->diameter();
776 std::vector<double> circle_ratios;
777 std::vector<double> unformity_factors;
785 if (polytope->is_locally_owned())
787 const std::vector<typename Triangulation<dim>::active_face_iterator>
788 &boundary = polytope->polytope_boundary();
790 const double diameter = polytope->diameter();
791 const double radius_circumscribed_circle = .5 *
diameter;
794 for (
unsigned int f = 0; f < boundary.size(); f += 1)
797 cdtp.insert_constraint(
798 {boundary[f]->vertex(0)[0], boundary[f]->vertex(0)[1]},
799 {boundary[f]->vertex(1)[0], boundary[f]->vertex(1)[1]});
801 cdtp.split_subconstraint_graph_into_constraints();
803 CGAL::Polygon_2<Kernel> outer_polygon;
804 auto it = outer_polygon.vertices_begin();
805 for (
typename CDTP::Constraint_id cid : cdtp.constraints())
807 for (
typename CDTP::Vertex_handle vh :
808 cdtp.vertices_in_constraint(cid))
810 it = outer_polygon.insert(outer_polygon.vertices_end(),
814 outer_polygon.erase(it);
816 const double radius_inscribed_circle =
817 compute_radius_inscribed_circle(outer_polygon);
819 circle_ratios.push_back(radius_inscribed_circle /
820 radius_circumscribed_circle);
821 unformity_factors.push_back(
diameter / mesh_size);
825 const auto &agglo_values = ah.
reinit(polytope);
826 const double measure_element =
827 std::accumulate(agglo_values.get_JxW_values().cbegin(),
828 agglo_values.get_JxW_values().cend(),
830 box_ratio.push_back(measure_element /
831 bboxes[polytope->index()].volume());
838 double covering_bboxes = 0.;
839 for (
unsigned int i = 0; i < bboxes.size(); ++i)
840 covering_bboxes += bboxes[i].
volume();
842 const double overlap_factor =
849 return {unformity_factors, circle_ratios, box_ratio, overlap_factor};
865 const std::string &filename)
867 static_assert(dim == 2);
868 std::ofstream myfile;
869 myfile.open(filename +
".csv");
872 if (polytope->is_locally_owned())
874 const std::vector<typename Triangulation<dim>::active_face_iterator>
875 &boundary = polytope->polytope_boundary();
876 for (
unsigned int f = 0; f < boundary.size(); ++f)
878 myfile << boundary[f]->vertex(0)[0];
880 myfile << boundary[f]->vertex(0)[1];
882 myfile << boundary[f]->vertex(1)[0];
884 myfile << boundary[f]->vertex(1)[1];
894 template <
typename T>
898 return (
pow >=
sizeof(
unsigned int) * 8) ? 0 :
907 const std::string &matrix_name,
910#ifdef DEAL_II_WITH_TRILINOS
911 const Epetra_CrsMatrix &trilinos_matrix = matrix.trilinos_matrix();
914 EpetraExt::RowMatrixToMatrixMarketFile(filename.c_str(),
936 template <
int dim,
int spacedim,
typename VectorType>
941 const VectorType &src)
943 Assert((dim == spacedim), ExcNotImplemented());
947 "The destination vector must the empt upon calling this function."));
949 using NumberType =
typename VectorType::value_type;
950 constexpr bool is_trilinos_vector =
951 std::is_same_v<VectorType, TrilinosWrappers::MPI::Vector>;
952 using MatrixType = std::conditional_t<is_trilinos_vector,
956 MatrixType interpolation_matrix;
959 typename std::conditional_t<!is_trilinos_vector, SparsityPattern, void *>
975 std::unique_ptr<FiniteElement<dim>> output_fe;
977 output_fe = std::make_unique<FE_DGQ<dim>>(fe.degree);
979 output_fe = std::make_unique<FE_SimplexDGP<dim>>(fe.degree);
988 const IndexSet locally_relevant_dofs =
996 locally_relevant_dofs);
998 std::vector<types::global_dof_index> agglo_dof_indices(fe.dofs_per_cell);
999 std::vector<types::global_dof_index> standard_dof_indices(
1001 std::vector<types::global_dof_index> output_dof_indices(
1002 output_fe->dofs_per_cell);
1011 if (cell->is_locally_owned())
1016 cell->active_cell_index());
1017 slaves.emplace_back(cell);
1019 cell->get_dof_indices(agglo_dof_indices);
1021 for (
const auto &slave : slaves)
1024 const auto slave_output =
1025 slave->as_dof_handler_iterator(*output_dh);
1026 slave_output->get_dof_indices(output_dof_indices);
1027 for (
const auto row : output_dof_indices)
1029 agglo_dof_indices.begin(),
1030 agglo_dof_indices.end());
1036 const auto assemble_interpolation_matrix = [&]() {
1038 std::vector<Point<dim>> reference_q_points(fe.dofs_per_cell);
1045 if (cell->is_locally_owned())
1050 cell->active_cell_index());
1051 slaves.emplace_back(cell);
1053 cell->get_dof_indices(agglo_dof_indices);
1061 for (
const auto &slave : slaves)
1064 const auto slave_output =
1065 slave->as_dof_handler_iterator(*output_dh);
1067 slave_output->get_dof_indices(output_dof_indices);
1068 output_fe_values.
reinit(slave_output);
1072 const auto &q_points =
1074 for (
const auto i : output_fe_values.
dof_indices())
1077 for (
const auto j : output_fe_values.
dof_indices())
1079 local_matrix(i, j) = fe.shape_value(j, p);
1085 interpolation_matrix);
1092 if constexpr (std::is_same_v<MatrixType, TrilinosWrappers::SparseMatrix>)
1098 locally_relevant_dofs);
1100 interpolation_matrix.reinit(locally_owned_dofs,
1101 locally_owned_dofs_agglo,
1104 dst.reinit(locally_owned_dofs);
1105 assemble_interpolation_matrix();
1107 else if constexpr (std::is_same_v<MatrixType, SparseMatrix<NumberType>>)
1110 interpolation_matrix.reinit(sp);
1111 dst.reinit(output_dh->
n_dofs());
1112 assemble_interpolation_matrix();
1117 (void)agglomeration_handler;
1129 interpolation_matrix.vmult(dst, src);
1145 template <
int dim,
int spacedim,
typename VectorType>
1150 const VectorType &src,
1151 const bool on_the_fly =
true)
1153 Assert((dim == spacedim), ExcNotImplemented());
1157 "The destination vector must the empt upon calling this function."));
1159 using NumberType =
typename VectorType::value_type;
1160 static constexpr bool is_trilinos_vector =
1161 std::is_same_v<VectorType, TrilinosWrappers::MPI::Vector>;
1163 static constexpr bool is_supported_vector =
1164 std::is_same_v<VectorType, Vector<NumberType>> || is_trilinos_vector;
1165 static_assert(is_supported_vector);
1168 if (on_the_fly ==
false)
1184 agglomeration_handler.
get_fe();
1190 std::unique_ptr<FiniteElement<dim>> output_fe;
1192 output_fe = std::make_unique<FE_DGQ<dim>>(original_fe.
degree);
1195 std::make_unique<FE_SimplexDGP<dim>>(original_fe.
degree);
1204 if constexpr (std::is_same_v<VectorType,
1207 const IndexSet &locally_owned_dofs =
1209 dst.reinit(locally_owned_dofs);
1211 else if constexpr (std::is_same_v<VectorType, Vector<NumberType>>)
1213 dst.reinit(output_dh.
n_dofs());
1218 (void)agglomeration_handler;
1226 const unsigned int dofs_per_cell =
1228 const unsigned int output_dofs_per_cell =
1229 output_fe->n_dofs_per_cell();
1236 std::vector<types::global_dof_index> local_dof_indices(
1238 std::vector<types::global_dof_index> local_dof_indices_output(
1239 output_dofs_per_cell);
1242 for (
const auto &polytope :
1245 if (polytope->is_locally_owned())
1247 polytope->get_dof_indices(local_dof_indices);
1250 const auto &deal_cells =
1251 polytope->get_agglomerate();
1252 for (
const auto &cell : deal_cells)
1254 const auto slave_output = cell->as_dof_handler_iterator(
1256 slave_output->get_dof_indices(local_dof_indices_output);
1257 output_fe_values.
reinit(slave_output);
1259 const auto &qpoints =
1262 for (
unsigned int j = 0; j < output_dofs_per_cell; ++j)
1264 const auto &ref_qpoint =
1266 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1267 dst(local_dof_indices_output[j]) +=
1268 src(local_dof_indices[i]) *
1290 Assert(original_fe_collection[0].n_components() >= 1,
1291 ExcMessage(
"Invalid FE: must have at least one component."));
1292 if (original_fe_collection[0].n_components() == 1)
1295 for (
unsigned int i = 0; i < original_fe_collection.
size(); ++i)
1297 std::unique_ptr<FiniteElement<dim>> output_fe;
1299 output_fe = std::make_unique<FE_DGQ<dim>>(
1300 original_fe_collection[i].degree);
1302 output_fe = std::make_unique<FE_SimplexDGP<dim>>(
1303 original_fe_collection[i].degree);
1306 output_fe_collection.
push_back(*output_fe);
1309 else if (original_fe_collection[0].n_components() > 1)
1312 for (
unsigned int i = 0; i < original_fe_collection.
size(); ++i)
1314 std::vector<const FiniteElement<dim, spacedim> *>
1316 std::vector<unsigned int> multiplicities;
1317 for (
unsigned int b = 0;
1318 b < original_fe_collection[i].n_base_elements();
1322 &original_fe_collection[i].base_element(
b)))
1323 base_elements.push_back(
1329 original_fe_collection[i]
1333 base_elements.push_back(
1335 original_fe_collection[i]
1341 multiplicities.push_back(
1342 original_fe_collection[i].element_multiplicity(
b));
1347 for (
const auto *ptr : base_elements)
1349 output_fe_collection.
push_back(output_fe_system);
1357 for (
const auto &polytope :
1360 if (polytope->is_locally_owned())
1362 const auto &deal_cells =
1363 polytope->get_agglomerate();
1364 const unsigned int active_fe_idx =
1365 polytope->active_fe_index();
1367 for (
const auto &cell : deal_cells)
1370 slave_cell_dh_iterator =
1371 cell->as_dof_handler_iterator(output_dh);
1372 slave_cell_dh_iterator->set_active_fe_index(
1379 if constexpr (std::is_same_v<VectorType,
1382 const IndexSet &locally_owned_dofs =
1384 dst.reinit(locally_owned_dofs);
1386 else if constexpr (std::is_same_v<VectorType, Vector<NumberType>>)
1388 dst.reinit(output_dh.
n_dofs());
1393 (void)agglomeration_handler;
1400 for (
const auto &polytope :
1403 if (polytope->is_locally_owned())
1405 const unsigned int active_fe_idx =
1406 polytope->active_fe_index();
1407 const unsigned int dofs_per_cell =
1408 polytope->get_fe().dofs_per_cell;
1409 const unsigned int output_dofs_per_cell =
1410 output_fe_collection[active_fe_idx].n_dofs_per_cell();
1412 .get_unit_support_points());
1415 output_fe_collection[active_fe_idx],
1418 std::vector<types::global_dof_index> local_dof_indices(
1420 std::vector<types::global_dof_index>
1421 local_dof_indices_output(output_dofs_per_cell);
1423 polytope->get_dof_indices(local_dof_indices);
1426 const auto &deal_cells =
1427 polytope->get_agglomerate();
1428 for (
const auto &cell : deal_cells)
1430 const auto slave_output = cell->as_dof_handler_iterator(
1432 slave_output->get_dof_indices(local_dof_indices_output);
1433 output_fe_values.
reinit(slave_output);
1435 const auto &qpoints =
1438 for (
unsigned int j = 0; j < output_dofs_per_cell; ++j)
1440 const unsigned int component_idx_of_this_dof =
1441 slave_output->get_fe()
1442 .system_to_component_index(j)
1444 const auto &ref_qpoint =
1446 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1447 dst(local_dof_indices_output[j]) +=
1448 src(local_dof_indices[i]) *
1449 original_fe_collection[active_fe_idx]
1450 .shape_value_component(
1451 i, ref_qpoint, component_idx_of_this_dof);
1469 template <
int dim,
int spacedim,
typename MatrixType>
1473 MatrixType &interpolation_matrix)
1475 Assert((dim == spacedim), ExcNotImplemented());
1477 using NumberType =
typename MatrixType::value_type;
1478 constexpr bool is_trilinos_matrix =
1479 std::is_same_v<MatrixType, TrilinosWrappers::MPI::Vector>;
1482 typename std::conditional_t<!is_trilinos_matrix, SparsityPattern, void *>
1501 const IndexSet locally_relevant_dofs =
1509 locally_relevant_dofs);
1511 std::vector<types::global_dof_index> agglo_dof_indices(fe.
dofs_per_cell);
1512 std::vector<types::global_dof_index> standard_dof_indices(fe.
dofs_per_cell);
1513 std::vector<types::global_dof_index> output_dof_indices(fe.
dofs_per_cell);
1522 if (cell->is_locally_owned())
1527 cell->active_cell_index());
1528 slaves.emplace_back(cell);
1530 cell->get_dof_indices(agglo_dof_indices);
1532 for (
const auto &slave : slaves)
1535 const auto slave_output =
1536 slave->as_dof_handler_iterator(*output_dh);
1537 slave_output->get_dof_indices(output_dof_indices);
1538 for (
const auto row : output_dof_indices)
1540 agglo_dof_indices.begin(),
1541 agglo_dof_indices.end());
1547 const auto assemble_interpolation_matrix = [&]() {
1549 std::vector<Point<dim>> reference_q_points(fe.
dofs_per_cell);
1556 if (cell->is_locally_owned())
1561 cell->active_cell_index());
1562 slaves.emplace_back(cell);
1564 cell->get_dof_indices(agglo_dof_indices);
1572 for (
const auto &slave : slaves)
1575 const auto slave_output =
1576 slave->as_dof_handler_iterator(*output_dh);
1578 slave_output->get_dof_indices(output_dof_indices);
1579 output_fe_values.
reinit(slave_output);
1583 const auto &q_points =
1585 for (
const auto i : output_fe_values.
dof_indices())
1588 for (
const auto j : output_fe_values.
dof_indices())
1596 interpolation_matrix);
1603 if constexpr (std::is_same_v<MatrixType, TrilinosWrappers::SparseMatrix>)
1609 locally_relevant_dofs);
1611 interpolation_matrix.reinit(locally_owned_dofs,
1612 locally_owned_dofs_agglo,
1615 assemble_interpolation_matrix();
1617 else if constexpr (std::is_same_v<MatrixType, SparseMatrix<NumberType>>)
1620 interpolation_matrix.reinit(sp);
1621 assemble_interpolation_matrix();
1626 (void)agglomeration_handler;
1647 template <
int dim,
typename Number,
typename VectorType>
1650 const VectorType &solution,
1652 const std::vector<VectorTools::NormType> &norms,
1653 std::vector<double> &global_errors)
1655 Assert(solution.size() > 0,
1657 "Solution vector must be non-empty upon calling this function."));
1658 Assert(std::any_of(norms.cbegin(),
1661 return (norm_type ==
1662 VectorTools::NormType::H1_seminorm ||
1663 norm_type == VectorTools::NormType::L2_norm);
1665 ExcMessage(
"Norm type not supported"));
1666 global_errors.resize(norms.size());
1667 std::fill(global_errors.begin(), global_errors.end(), 0.);
1670 std::vector<double> local_errors(norms.size());
1671 std::fill(local_errors.begin(), local_errors.end(), 0.);
1674 const unsigned int dofs_per_cell = agglomeration_handler.
n_dofs_per_cell();
1676 const bool compute_semi_H1 =
1677 std::any_of(norms.cbegin(),
1680 return norm_type == VectorTools::NormType::H1_seminorm;
1683 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1686 if (polytope->is_locally_owned())
1688 const auto &agglo_values = agglomeration_handler.
reinit(polytope);
1689 polytope->get_dof_indices(local_dof_indices);
1692 const unsigned int n_qpoints = q_points.size();
1693 std::vector<double> analyical_sol_at_qpoints(n_qpoints);
1694 exact_solution.
value_list(q_points, analyical_sol_at_qpoints);
1695 std::vector<Tensor<1, dim>> grad_analyical_sol_at_qpoints(
1698 if (compute_semi_H1)
1700 grad_analyical_sol_at_qpoints);
1702 for (
unsigned int q_index : agglo_values.quadrature_point_indices())
1704 double solution_at_qpoint = 0.;
1706 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1708 solution_at_qpoint += solution(local_dof_indices[i]) *
1709 agglo_values.shape_value(i, q_index);
1711 if (compute_semi_H1)
1712 grad_solution_at_qpoint +=
1713 solution(local_dof_indices[i]) *
1714 agglo_values.shape_grad(i, q_index);
1717 local_errors[0] +=
std::pow((analyical_sol_at_qpoints[q_index] -
1718 solution_at_qpoint),
1720 agglo_values.JxW(q_index);
1723 if (compute_semi_H1)
1724 for (
unsigned int d = 0;
d < dim; ++
d)
1726 std::pow((grad_analyical_sol_at_qpoints[q_index][
d] -
1727 grad_solution_at_qpoint[
d]),
1729 agglo_values.JxW(q_index);
1738 [](
const double a,
const double b) { return a + b; });
1740 global_errors[0] =
std::sqrt(global_errors[0]);
1742 if (compute_semi_H1)
1747 [](
const double a,
const double b) { return a + b; });
1748 global_errors[1] =
std::sqrt(global_errors[1]);
1766 &agglomeration_handlers,
1769 const unsigned int starting_tree_level)
1771 const auto parallel_tria =
1775 Assert(parallel_tria->n_active_cells() > 0, ExcInternalError());
1777 const MPI_Comm
comm = parallel_tria->get_mpi_communicator();
1783 static constexpr unsigned int max_elem_per_node =
1785 std::vector<std::pair<BoundingBox<dim>,
1787 boxes(parallel_tria->n_locally_owned_active_cells());
1789 for (
const auto &cell : parallel_tria->active_cell_iterators())
1790 if (cell->is_locally_owned())
1794 Assert(n_levels(tree) >= 2, ExcMessage(
"At least two levels are needed."));
1795 pcout <<
"Total number of available levels: " << n_levels(tree)
1798 pcout <<
"Starting level: " << starting_tree_level << std::endl;
1799 const unsigned int total_tree_levels =
1800 n_levels(tree) - starting_tree_level + 1;
1805 agglomeration_handlers.resize(total_tree_levels);
1807 for (
unsigned int extraction_level = starting_tree_level;
1808 extraction_level <= n_levels(tree);
1811 agglomeration_handlers[extraction_level - starting_tree_level] =
1812 std::make_unique<AgglomerationHandler<dim>>(cached_tria);
1816 agglomeration_handlers[extraction_level - starting_tree_level]
1817 ->connect_hierarchy(agglomerator);
1820 unsigned int agglo_index = 0;
1821 for (
unsigned int i = 0; i < agglomerates.size(); ++i)
1823 const auto &agglo = agglomerates[i];
1824 for (
const auto &el : agglo)
1826 el->set_material_id(agglo_index);
1831 const unsigned int n_local_agglomerates = agglo_index;
1832 unsigned int total_agglomerates =
1834 pcout <<
"Total agglomerates per (tree) level: " << extraction_level
1835 <<
": " << total_agglomerates << std::endl;
1840 std::vector<typename Triangulation<dim>::active_cell_iterator>>
1841 cells_per_subdomain(n_local_agglomerates);
1842 for (
const auto &cell : parallel_tria->active_cell_iterators())
1843 if (cell->is_locally_owned())
1844 cells_per_subdomain[cell->material_id()].push_back(cell);
1847 for (std::size_t i = 0; i < cells_per_subdomain.size(); ++i)
1848 agglomeration_handlers[extraction_level - starting_tree_level]
1849 ->define_agglomerate(cells_per_subdomain[i]);
1851 agglomeration_handlers[extraction_level - starting_tree_level]
1857 agglomeration_handlers[extraction_level - starting_tree_level]
1858 ->distribute_agglomerated_dofs(fe_dg);
1861 return total_tree_levels;
1878 const double penalty_constant,
1882 const unsigned int dofs_per_cell =
1887 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1889 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
1891 M11(i, j) += (-0.5 * fe_faces0.
shape_grad(i, q_index) * normal *
1893 0.5 * fe_faces0.
shape_grad(j, q_index) * normal *
1895 (penalty_constant / h_f) *
1898 fe_faces0.
JxW(q_index);
1899 M12(i, j) += (0.5 * fe_faces0.
shape_grad(i, q_index) * normal *
1901 0.5 * fe_faces1.
shape_grad(j, q_index) * normal *
1903 (penalty_constant / h_f) *
1906 fe_faces1.
JxW(q_index);
1907 M21(i, j) += (-0.5 * fe_faces1.
shape_grad(i, q_index) * normal *
1909 0.5 * fe_faces0.
shape_grad(j, q_index) * normal *
1911 (penalty_constant / h_f) *
1914 fe_faces1.
JxW(q_index);
1915 M22(i, j) += (0.5 * fe_faces1.
shape_grad(i, q_index) * normal *
1917 0.5 * fe_faces1.
shape_grad(j, q_index) * normal *
1919 (penalty_constant / h_f) *
1922 fe_faces1.
JxW(q_index);
1938 const std::vector<std::vector<double>> &recv_values,
1940 const std::vector<double> &recv_jxws,
1941 const double penalty_constant,
1945 (recv_values.size() > 0 && recv_gradients.size() && recv_jxws.size()),
1947 "Not possible to assemble jumps and averages at a ghosted interface."));
1948 const unsigned int dofs_per_cell = M11.
m();
1953 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1955 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
1957 M11(i, j) += (-0.5 * fe_faces0.
shape_grad(i, q_index) * normal *
1959 0.5 * fe_faces0.
shape_grad(j, q_index) * normal *
1961 (penalty_constant / h_f) *
1964 fe_faces0.
JxW(q_index);
1965 M12(i, j) += (0.5 * fe_faces0.
shape_grad(i, q_index) * normal *
1966 recv_values[j][q_index] -
1967 0.5 * recv_gradients[j][q_index] * normal *
1969 (penalty_constant / h_f) *
1971 recv_values[j][q_index]) *
1974 (-0.5 * recv_gradients[i][q_index] * normal *
1976 0.5 * fe_faces0.
shape_grad(j, q_index) * normal *
1977 recv_values[i][q_index] -
1978 (penalty_constant / h_f) * recv_values[i][q_index] *
1982 (0.5 * recv_gradients[i][q_index] * normal *
1983 recv_values[j][q_index] +
1984 0.5 * recv_gradients[j][q_index] * normal *
1985 recv_values[i][q_index] +
1986 (penalty_constant / h_f) * recv_values[i][q_index] *
1987 recv_values[j][q_index]) *
2000 template <
int dim,
typename MatrixType>
2007 (std::is_same_v<MatrixType, TrilinosWrappers::SparseMatrix> ||
2008 std::is_same_v<MatrixType,
2014 ExcMessage(
"FE type not supported."));
2017 constraints.
close();
2018 const double penalty_constant =
2022 .create_agglomeration_sparsity_pattern(dsp);
2023 system_matrix.reinit(dsp);
2030 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
2031 std::vector<types::global_dof_index> local_dof_indices_neighbor(
2036 if (polytope->is_locally_owned())
2039 const auto &agglo_values = ah.
reinit(polytope);
2040 for (
unsigned int q_index : agglo_values.quadrature_point_indices())
2042 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2044 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
2046 cell_matrix(i, j) +=
2047 agglo_values.shape_grad(i, q_index) *
2048 agglo_values.shape_grad(j, q_index) *
2049 agglo_values.JxW(q_index);
2054 polytope->get_dof_indices(local_dof_indices);
2056 unsigned int n_faces = polytope->n_faces();
2057 const double h_f = polytope->diameter();
2058 for (
unsigned int f = 0; f < n_faces; ++f)
2060 if (polytope->at_boundary(f))
2063 const auto &fe_face = ah.
reinit(polytope, f);
2065 for (
unsigned int q_index :
2066 fe_face.quadrature_point_indices())
2069 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2071 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
2073 cell_matrix(i, j) +=
2074 (-fe_face.shape_value(i, q_index) *
2075 fe_face.shape_grad(j, q_index) * normal -
2076 fe_face.shape_grad(i, q_index) * normal *
2077 fe_face.shape_value(j, q_index) +
2078 (penalty_constant / h_f) *
2079 fe_face.shape_value(i, q_index) *
2080 fe_face.shape_value(j, q_index)) *
2081 fe_face.JxW(q_index);
2088 const auto &neigh_polytope = polytope->neighbor(f);
2089 if (polytope->id() < neigh_polytope->id())
2092 polytope->neighbor_of_agglomerated_neighbor(f);
2093 Assert(neigh_polytope->neighbor(nofn)->id() ==
2095 ExcMessage(
"Mismatch."));
2097 polytope, neigh_polytope, f, nofn);
2098 const auto &fe_faces0 = fe_faces.first;
2099 if (neigh_polytope->is_locally_owned())
2102 const auto &fe_faces1 = fe_faces.second;
2117 neigh_polytope->get_dof_indices(
2118 local_dof_indices_neighbor);
2120 M11, local_dof_indices, system_matrix);
2124 local_dof_indices_neighbor,
2128 local_dof_indices_neighbor,
2132 M22, local_dof_indices_neighbor, system_matrix);
2139 neigh_polytope->subdomain_id();
2140 const auto &recv_jxws =
2142 .at({neigh_polytope->id(), nofn});
2143 const auto &recv_values =
2145 .at({neigh_polytope->id(), nofn});
2146 const auto &recv_gradients =
2148 .at({neigh_polytope->id(), nofn});
2169 neigh_polytope->get_dof_indices(
2170 local_dof_indices_neighbor);
2172 M11, local_dof_indices, system_matrix);
2176 local_dof_indices_neighbor,
2180 local_dof_indices_neighbor,
2184 M22, local_dof_indices_neighbor, system_matrix);
2204 template <
int dim,
typename MatrixType,
typename VectorType>
2207 VectorType &system_rhs,
2213 (std::is_same_v<MatrixType, TrilinosWrappers::SparseMatrix> ||
2214 std::is_same_v<MatrixType,
2219 "Implemented only for simplex meshes for the time being."));
2222 ExcNotImplemented());
2224 const double penalty_constant = .5 * fe_dg.
degree * (fe_dg.
degree + 1);
2226 constraints.
close();
2229 const IndexSet locally_relevant_dofs =
2238 locally_relevant_dofs);
2240 system_matrix.reinit(locally_owned_dofs,
2247 const unsigned int quadrature_degree = fe_dg.
degree + 1;
2278 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
2283 if (cell->is_locally_owned())
2295 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2297 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
2299 cell_matrix(i, j) += fe_values.
shape_grad(i, q_index) *
2301 fe_values.
JxW(q_index);
2305 fe_values.
JxW(q_index);
2310 cell->get_dof_indices(local_dof_indices);
2312 for (
const auto f : cell->face_indices())
2314 const double extent1 =
2315 cell->measure() / cell->face(f)->measure();
2317 if (cell->face(f)->at_boundary())
2319 hf = (1. / extent1 + 1. / extent1);
2320 fe_faces0.
reinit(cell, f);
2323 for (
unsigned int q_index :
2326 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2328 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
2330 cell_matrix(i, j) +=
2337 (penalty_constant * hf) *
2340 fe_faces0.
JxW(q_index);
2349 const auto &neigh_cell = cell->neighbor(f);
2350 if (cell->global_active_cell_index() <
2351 neigh_cell->global_active_cell_index())
2353 const double extent2 =
2354 neigh_cell->measure() /
2355 neigh_cell->face(cell->neighbor_of_neighbor(f))
2357 hf = (1. / extent1 + 1. / extent2);
2358 fe_faces0.
reinit(cell, f);
2359 fe_faces1.
reinit(neigh_cell,
2360 cell->neighbor_of_neighbor(f));
2362 std::vector<types::global_dof_index>
2363 local_dof_indices_neighbor(dofs_per_cell);
2372 for (
unsigned int q_index :
2375 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2377 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
2386 (penalty_constant * hf) *
2389 fe_faces0.
JxW(q_index);
2398 (penalty_constant * hf) *
2401 fe_faces1.
JxW(q_index);
2411 (penalty_constant * hf) *
2414 fe_faces1.
JxW(q_index);
2424 (penalty_constant * hf) *
2427 fe_faces1.
JxW(q_index);
2434 neigh_cell->get_dof_indices(local_dof_indices_neighbor);
2437 M11, local_dof_indices, system_matrix);
2441 local_dof_indices_neighbor,
2445 local_dof_indices_neighbor,
2449 M22, local_dof_indices_neighbor, system_matrix);
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
Point< spacedim, Number > real_to_unit(const Point< spacedim, Number > &point) const
void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
const Triangulation< dim, spacedim > & get_triangulation() const
const IndexSet & locally_owned_dofs() const
void reinit(const Triangulation< dim, spacedim > &tria)
types::global_dof_index n_dofs() const
MPI_Comm get_mpi_communicator() const
void add_entries(const size_type row, ForwardIterator begin, ForwardIterator end, const bool indices_are_unique_and_sorted=false)
void reinit(const size_type m, const size_type n, const IndexSet &rowset=IndexSet())
void add(const size_type i, const size_type j)
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, level_dof_access > > &cell, const unsigned int face_no)
const std::vector< Point< spacedim > > & get_quadrature_points() const
const std::vector< Tensor< 1, spacedim > > & get_normal_vectors() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > dof_indices() const
std_cxx20::ranges::iota_view< unsigned int, unsigned int > quadrature_point_indices() const
const Tensor< 1, spacedim > & shape_grad(const unsigned int i, const unsigned int q_point) const
double JxW(const unsigned int q_point) const
const double & shape_value(const unsigned int i, const unsigned int q_point) const
void reinit(const TriaIterator< DoFCellAccessor< dim, spacedim, level_dof_access > > &cell)
const unsigned int degree
unsigned int n_dofs_per_cell() const
const unsigned int dofs_per_cell
const std::vector< Point< dim > > & get_unit_support_points() const
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
virtual void gradient_list(const std::vector< Point< dim > > &points, std::vector< Tensor< 1, dim, RangeNumberType > > &gradients, const unsigned int component=0) const
virtual void value_list(const std::vector< Point< dim > > &points, std::vector< RangeNumberType > &values, const unsigned int component=0) const
virtual BoundingBox< spacedim > get_bounding_box(const typename Triangulation< dim, spacedim >::cell_iterator &cell) const
void copy_from(const size_type n_rows, const size_type n_cols, const ForwardIterator begin, const ForwardIterator end)
bool all_reference_cells_are_hyper_cube() const
virtual MPI_Comm get_mpi_communicator() const
bool all_reference_cells_are_simplex() const
unsigned int n_dofs_per_cell() const noexcept
types::global_cell_index cell_to_polytope_index(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell) const
const DoFHandler< dim, spacedim > & get_dof_handler() const
const std::vector< typename Triangulation< dim, spacedim >::active_cell_iterator > & get_slaves_of_idx(types::global_cell_index idx) const
const FEValues< dim, spacedim > & reinit(const AgglomerationIterator< dim, spacedim > &polytope) const
std::map< types::subdomain_id, std::map< std::pair< CellId, unsigned int >, std::vector< double > > > recv_jxws
DoFHandler< dim, spacedim > output_dh
std::pair< const FEValuesBase< dim, spacedim > &, const FEValuesBase< dim, spacedim > & > reinit_interface(const AgglomerationIterator< dim, spacedim > &polytope_in, const AgglomerationIterator< dim, spacedim > &neigh_polytope, const unsigned int local_in, const unsigned int local_outside) const
std::map< types::subdomain_id, std::map< std::pair< CellId, unsigned int >, std::vector< std::vector< Tensor< 1, spacedim > > > > > recv_gradients
const Triangulation< dim, spacedim > & get_triangulation() const
const Mapping< dim > & get_mapping() const
unsigned int n_agglomerates() const
const std::vector< BoundingBox< dim > > & get_local_bboxes() const
const FiniteElement< dim, spacedim > & get_fe() const
std::map< types::subdomain_id, std::map< std::pair< CellId, unsigned int >, std::vector< std::vector< double > > > > recv_values
bool is_master_cell(const CellIterator &cell) const
IteratorRange< agglomeration_iterator > polytope_iterators() const
agglomeration_iterator define_agglomerate(const AgglomerationContainer &cells)
DoFHandler< dim, spacedim > agglo_dh
bool used_fe_collection() const
const hp::FECollection< dim, spacedim > & get_fe_collection() const
const std::vector< std::vector< typename Triangulation< dim >::active_cell_iterator > > & extract_agglomerates()
unsigned int size() const
void push_back(const FiniteElement< dim, spacedim > &new_fe)
IteratorRange< active_cell_iterator > active_cell_iterators() const
IteratorRange< active_cell_iterator > active_cell_iterators() const
static ::ExceptionBase & ExcTrilinosError(int arg1)
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertThrow(cond, exc)
void make_flux_sparsity_pattern(const DoFHandler< dim, spacedim > &dof_handler, SparsityPatternBase &sparsity_pattern)
Expression pow(const Expression &base, const Expression &exponent)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
T sum(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
T reduce(const T &local_value, const MPI_Comm comm, const std::function< T(const T &, const T &)> &combiner, const unsigned int root_process=0)
void get_face_connectivity_of_cells(const parallel::fullydistributed::Triangulation< dim, spacedim > &triangulation, DynamicSparsityPattern &cell_connectivity, const std::vector< types::global_cell_index > locally_owned_cells)
void interpolate_to_fine_grid(const AgglomerationHandler< dim, spacedim > &agglomeration_handler, VectorType &dst, const VectorType &src)
types::global_cell_index get_index(const std::vector< types::global_cell_index > &v, const types::global_cell_index index)
void partition_locally_owned_regions(const unsigned int n_partitions, Triangulation< dim, spacedim > &triangulation, const SparsityTools::Partitioner partitioner)
void fill_interpolation_matrix(const AgglomerationHandler< dim, spacedim > &agglomeration_handler, MatrixType &interpolation_matrix)
void assemble_local_jumps_and_averages(FullMatrix< double > &M11, FullMatrix< double > &M12, FullMatrix< double > &M21, FullMatrix< double > &M22, const FEValuesBase< dim > &fe_faces0, const FEValuesBase< dim > &fe_faces1, const double penalty_constant, const double h_f)
std::pair< std::vector< std::vector< unsigned int > >, std::vector< std::vector< typename Triangulation< boost::geometry::dimension< typename Rtree::indexable_type >::value >::active_cell_iterator > > > extract_children_of_level(const Rtree &tree, const unsigned int level)
void interpolate_to_fine_grid(const AgglomerationHandler< dim, spacedim > &agglomeration_handler, VectorType &dst, const VectorType &src, const bool on_the_fly=true)
void compute_global_error(const AgglomerationHandler< dim > &agglomeration_handler, const VectorType &solution, const Function< dim, Number > &exact_solution, const std::vector< VectorTools::NormType > &norms, std::vector< double > &global_errors)
Number compute_h_orthogonal(const unsigned int face_index, const std::vector< typename Triangulation< dim >::active_face_iterator > &polygon_boundary, const Tensor< 1, dim > &deal_normal)
unsigned int construct_agglomerated_levels(const Triangulation< dim > &tria, std::vector< std::unique_ptr< AgglomerationHandler< dim > > > &agglomeration_handlers, const FE_DGQ< dim > &fe_dg, const Mapping< dim > &mapping, const unsigned int starting_tree_level)
constexpr T constexpr_pow(T num, unsigned int pow)
void assemble_dg_matrix(MatrixType &system_matrix, const FiniteElement< dim > &fe_dg, const AgglomerationHandler< dim > &ah)
void collect_cells_for_agglomeration(const Triangulation< dim, spacedim > &tria, const std::vector< types::global_cell_index > &cell_idxs, std::vector< typename Triangulation< dim, spacedim >::active_cell_iterator > &cells_to_be_agglomerated)
void assemble_local_jumps_and_averages_ghost(FullMatrix< double > &M11, FullMatrix< double > &M12, FullMatrix< double > &M21, FullMatrix< double > &M22, const FEValuesBase< dim > &fe_faces0, const std::vector< std::vector< double > > &recv_values, const std::vector< std::vector< Tensor< 1, dim > > > &recv_gradients, const std::vector< double > &recv_jxws, const double penalty_constant, const double h_f)
void assemble_dg_matrix_on_standard_mesh(MatrixType &system_matrix, VectorType &system_rhs, const Mapping< dim > &mapping, const FiniteElement< dim > &fe_dg, const DoFHandler< dim > &dof_handler)
void write_to_matrix_market_format(const std::string &filename, const std::string &matrix_name, const TrilinosWrappers::SparseMatrix &matrix)
void export_polygon_to_csv_file(const AgglomerationHandler< dim > &agglomeration_handler, const std::string &filename)
std::tuple< std::vector< double >, std::vector< double >, std::vector< double >, double > compute_quality_metrics(const AgglomerationHandler< dim > &ah)
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > pow(const ::VectorizedArray< Number, width > &, const Number p)
unsigned int subdomain_id
unsigned int global_cell_index
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
*braid_SplitCommworld & comm
RTree< typename LeafTypeIterator::value_type, IndexType, IndexableGetter > pack_rtree(const LeafTypeIterator &begin, const LeafTypeIterator &end)
const Translator & translator
void operator()(const InternalNode &node)
std::vector< std::vector< typename Triangulation< boost::geometry::dimension< Box >::value >::active_cell_iterator > > & agglomerates
Rtree_visitor(const Translator &translator, unsigned int target_level, std::vector< std::vector< typename Triangulation< boost::geometry::dimension< Box >::value >::active_cell_iterator > > &boxes, std::vector< std::vector< unsigned int > > &csr)
const size_t target_level
std::vector< std::vector< unsigned int > > & row_ptr
typename boost::geometry::index::detail::rtree::leaf< Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag >::type Leaf
size_t next_level_leafs_processed
typename boost::geometry::index::detail::rtree::internal_node< Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag >::type InternalNode