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,
242 const Translator &translator,
243 const unsigned int target_level,
245 boost::geometry::dimension<Box>::value>::active_cell_iterator>>
247 std::vector<std::vector<unsigned int>> &csr)
248 : translator(translator)
251 , next_level_leafs_processed(0)
252 , target_level(target_level)
253 , agglomerates(bb_in_boxes)
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);
274 if (
level < target_level)
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;
289 else if (
level == target_level)
292 const auto offset = agglomerates.size();
293 agglomerates.resize(offset + 1);
294 row_ptr.resize(row_ptr.size() + 1);
295 next_level_leafs_processed = 0;
296 row_ptr.back().push_back(
297 next_level_leafs_processed);
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;
312 else if (
level > target_level)
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;
325 row_ptr[node_counter].push_back(next_level_leafs_processed);
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)
349 agglomerates[node_counter].push_back(it.second);
351 next_level_leafs_processed += elements.size();
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 &
center{
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)
1181 agglomeration_handler.
get_fe();
1186 std::unique_ptr<FiniteElement<dim>> output_fe;
1188 output_fe = std::make_unique<FE_DGQ<dim>>(original_fe.
degree);
1190 output_fe = std::make_unique<FE_SimplexDGP<dim>>(original_fe.
degree);
1199 if constexpr (std::is_same_v<VectorType, TrilinosWrappers::MPI::Vector>)
1202 dst.reinit(locally_owned_dofs);
1204 else if constexpr (std::is_same_v<VectorType, Vector<NumberType>>)
1206 dst.reinit(output_dh.
n_dofs());
1211 (void)agglomeration_handler;
1219 const unsigned int dofs_per_cell =
1221 const unsigned int output_dofs_per_cell = output_fe->n_dofs_per_cell();
1228 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1229 std::vector<types::global_dof_index> local_dof_indices_output(
1230 output_dofs_per_cell);
1235 if (polytope->is_locally_owned())
1237 polytope->get_dof_indices(local_dof_indices);
1240 const auto &deal_cells =
1241 polytope->get_agglomerate();
1242 for (
const auto &cell : deal_cells)
1244 const auto slave_output = cell->as_dof_handler_iterator(
1246 slave_output->get_dof_indices(local_dof_indices_output);
1247 output_fe_values.
reinit(slave_output);
1249 const auto &qpoints =
1252 for (
unsigned int j = 0; j < output_dofs_per_cell; ++j)
1255 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1256 dst(local_dof_indices_output[j]) +=
1257 src(local_dof_indices[i]) *
1275 template <
int dim,
int spacedim,
typename MatrixType>
1279 MatrixType &interpolation_matrix)
1281 Assert((dim == spacedim), ExcNotImplemented());
1283 using NumberType =
typename MatrixType::value_type;
1284 constexpr bool is_trilinos_matrix =
1285 std::is_same_v<MatrixType, TrilinosWrappers::MPI::Vector>;
1288 typename std::conditional_t<!is_trilinos_matrix, SparsityPattern, void *>
1307 const IndexSet locally_relevant_dofs =
1315 locally_relevant_dofs);
1317 std::vector<types::global_dof_index> agglo_dof_indices(fe.
dofs_per_cell);
1318 std::vector<types::global_dof_index> standard_dof_indices(fe.
dofs_per_cell);
1319 std::vector<types::global_dof_index> output_dof_indices(fe.
dofs_per_cell);
1328 if (cell->is_locally_owned())
1333 cell->active_cell_index());
1334 slaves.emplace_back(cell);
1336 cell->get_dof_indices(agglo_dof_indices);
1338 for (
const auto &slave : slaves)
1341 const auto slave_output =
1342 slave->as_dof_handler_iterator(*output_dh);
1343 slave_output->get_dof_indices(output_dof_indices);
1344 for (
const auto row : output_dof_indices)
1346 agglo_dof_indices.begin(),
1347 agglo_dof_indices.end());
1353 const auto assemble_interpolation_matrix = [&]() {
1355 std::vector<Point<dim>> reference_q_points(fe.
dofs_per_cell);
1362 if (cell->is_locally_owned())
1367 cell->active_cell_index());
1368 slaves.emplace_back(cell);
1370 cell->get_dof_indices(agglo_dof_indices);
1378 for (
const auto &slave : slaves)
1381 const auto slave_output =
1382 slave->as_dof_handler_iterator(*output_dh);
1384 slave_output->get_dof_indices(output_dof_indices);
1385 output_fe_values.
reinit(slave_output);
1389 const auto &q_points =
1391 for (
const auto i : output_fe_values.
dof_indices())
1394 for (
const auto j : output_fe_values.
dof_indices())
1402 interpolation_matrix);
1409 if constexpr (std::is_same_v<MatrixType, TrilinosWrappers::SparseMatrix>)
1415 locally_relevant_dofs);
1417 interpolation_matrix.reinit(locally_owned_dofs,
1418 locally_owned_dofs_agglo,
1421 assemble_interpolation_matrix();
1423 else if constexpr (std::is_same_v<MatrixType, SparseMatrix<NumberType>>)
1426 interpolation_matrix.reinit(sp);
1427 assemble_interpolation_matrix();
1432 (void)agglomeration_handler;
1453 template <
int dim,
typename Number,
typename VectorType>
1456 const VectorType &solution,
1458 const std::vector<VectorTools::NormType> &norms,
1459 std::vector<double> &global_errors)
1461 Assert(solution.size() > 0,
1463 "Solution vector must be non-empty upon calling this function."));
1464 Assert(std::any_of(norms.cbegin(),
1467 return (norm_type ==
1468 VectorTools::NormType::H1_seminorm ||
1469 norm_type == VectorTools::NormType::L2_norm);
1471 ExcMessage(
"Norm type not supported"));
1472 global_errors.resize(norms.size());
1473 std::fill(global_errors.begin(), global_errors.end(), 0.);
1476 std::vector<double> local_errors(norms.size());
1477 std::fill(local_errors.begin(), local_errors.end(), 0.);
1480 const unsigned int dofs_per_cell = agglomeration_handler.
n_dofs_per_cell();
1482 const bool compute_semi_H1 =
1483 std::any_of(norms.cbegin(),
1486 return norm_type == VectorTools::NormType::H1_seminorm;
1489 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1492 if (polytope->is_locally_owned())
1494 const auto &agglo_values = agglomeration_handler.
reinit(polytope);
1495 polytope->get_dof_indices(local_dof_indices);
1498 const unsigned int n_qpoints = q_points.size();
1499 std::vector<double> analyical_sol_at_qpoints(n_qpoints);
1500 exact_solution.
value_list(q_points, analyical_sol_at_qpoints);
1501 std::vector<Tensor<1, dim>> grad_analyical_sol_at_qpoints(
1504 if (compute_semi_H1)
1506 grad_analyical_sol_at_qpoints);
1508 for (
unsigned int q_index : agglo_values.quadrature_point_indices())
1510 double solution_at_qpoint = 0.;
1512 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1514 solution_at_qpoint += solution(local_dof_indices[i]) *
1515 agglo_values.shape_value(i, q_index);
1517 if (compute_semi_H1)
1518 grad_solution_at_qpoint +=
1519 solution(local_dof_indices[i]) *
1520 agglo_values.shape_grad(i, q_index);
1523 local_errors[0] +=
std::pow((analyical_sol_at_qpoints[q_index] -
1524 solution_at_qpoint),
1526 agglo_values.JxW(q_index);
1529 if (compute_semi_H1)
1530 for (
unsigned int d = 0;
d < dim; ++
d)
1532 std::pow((grad_analyical_sol_at_qpoints[q_index][
d] -
1533 grad_solution_at_qpoint[
d]),
1535 agglo_values.JxW(q_index);
1544 [](
const double a,
const double b) { return a + b; });
1546 global_errors[0] =
std::sqrt(global_errors[0]);
1548 if (compute_semi_H1)
1553 [](
const double a,
const double b) { return a + b; });
1554 global_errors[1] =
std::sqrt(global_errors[1]);
1572 &agglomeration_handlers,
1575 const unsigned int starting_tree_level)
1577 const auto parallel_tria =
1581 Assert(parallel_tria->n_active_cells() > 0, ExcInternalError());
1583 const MPI_Comm
comm = parallel_tria->get_communicator();
1589 static constexpr unsigned int max_elem_per_node =
1591 std::vector<std::pair<BoundingBox<dim>,
1593 boxes(parallel_tria->n_locally_owned_active_cells());
1595 for (
const auto &cell : parallel_tria->active_cell_iterators())
1596 if (cell->is_locally_owned())
1599 auto tree = pack_rtree<bgi::rstar<max_elem_per_node>>(boxes);
1600 Assert(n_levels(tree) >= 2, ExcMessage(
"At least two levels are needed."));
1601 pcout <<
"Total number of available levels: " << n_levels(tree)
1604 pcout <<
"Starting level: " << starting_tree_level << std::endl;
1605 const unsigned int total_tree_levels =
1606 n_levels(tree) - starting_tree_level + 1;
1611 agglomeration_handlers.resize(total_tree_levels);
1613 for (
unsigned int extraction_level = starting_tree_level;
1614 extraction_level <= n_levels(tree);
1617 agglomeration_handlers[extraction_level - starting_tree_level] =
1618 std::make_unique<AgglomerationHandler<dim>>(cached_tria);
1622 agglomeration_handlers[extraction_level - starting_tree_level]
1623 ->connect_hierarchy(agglomerator);
1626 unsigned int agglo_index = 0;
1627 for (
unsigned int i = 0; i < agglomerates.size(); ++i)
1629 const auto &agglo = agglomerates[i];
1630 for (
const auto &el : agglo)
1632 el->set_material_id(agglo_index);
1637 const unsigned int n_local_agglomerates = agglo_index;
1638 unsigned int total_agglomerates =
1640 pcout <<
"Total agglomerates per (tree) level: " << extraction_level
1641 <<
": " << total_agglomerates << std::endl;
1646 std::vector<typename Triangulation<dim>::active_cell_iterator>>
1647 cells_per_subdomain(n_local_agglomerates);
1648 for (
const auto &cell : parallel_tria->active_cell_iterators())
1649 if (cell->is_locally_owned())
1650 cells_per_subdomain[cell->material_id()].push_back(cell);
1653 for (std::size_t i = 0; i < cells_per_subdomain.size(); ++i)
1654 agglomeration_handlers[extraction_level - starting_tree_level]
1655 ->define_agglomerate(cells_per_subdomain[i]);
1657 agglomeration_handlers[extraction_level - starting_tree_level]
1663 agglomeration_handlers[extraction_level - starting_tree_level]
1664 ->distribute_agglomerated_dofs(fe_dg);
1667 return total_tree_levels;
1684 const double penalty_constant,
1688 const unsigned int dofs_per_cell =
1693 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1695 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
1697 M11(i, j) += (-0.5 * fe_faces0.
shape_grad(i, q_index) * normal *
1699 0.5 * fe_faces0.
shape_grad(j, q_index) * normal *
1701 (penalty_constant / h_f) *
1704 fe_faces0.
JxW(q_index);
1705 M12(i, j) += (0.5 * fe_faces0.
shape_grad(i, q_index) * normal *
1707 0.5 * fe_faces1.
shape_grad(j, q_index) * normal *
1709 (penalty_constant / h_f) *
1712 fe_faces1.
JxW(q_index);
1713 M21(i, j) += (-0.5 * fe_faces1.
shape_grad(i, q_index) * normal *
1715 0.5 * fe_faces0.
shape_grad(j, q_index) * normal *
1717 (penalty_constant / h_f) *
1720 fe_faces1.
JxW(q_index);
1721 M22(i, j) += (0.5 * fe_faces1.
shape_grad(i, q_index) * normal *
1723 0.5 * fe_faces1.
shape_grad(j, q_index) * normal *
1725 (penalty_constant / h_f) *
1728 fe_faces1.
JxW(q_index);
1744 const std::vector<std::vector<double>> &recv_values,
1746 const std::vector<double> &recv_jxws,
1747 const double penalty_constant,
1751 (recv_values.size() > 0 && recv_gradients.size() && recv_jxws.size()),
1753 "Not possible to assemble jumps and averages at a ghosted interface."));
1754 const unsigned int dofs_per_cell = M11.
m();
1759 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1761 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
1763 M11(i, j) += (-0.5 * fe_faces0.
shape_grad(i, q_index) * normal *
1765 0.5 * fe_faces0.
shape_grad(j, q_index) * normal *
1767 (penalty_constant / h_f) *
1770 fe_faces0.
JxW(q_index);
1771 M12(i, j) += (0.5 * fe_faces0.
shape_grad(i, q_index) * normal *
1772 recv_values[j][q_index] -
1773 0.5 * recv_gradients[j][q_index] * normal *
1775 (penalty_constant / h_f) *
1777 recv_values[j][q_index]) *
1780 (-0.5 * recv_gradients[i][q_index] * normal *
1782 0.5 * fe_faces0.
shape_grad(j, q_index) * normal *
1783 recv_values[i][q_index] -
1784 (penalty_constant / h_f) * recv_values[i][q_index] *
1788 (0.5 * recv_gradients[i][q_index] * normal *
1789 recv_values[j][q_index] +
1790 0.5 * recv_gradients[j][q_index] * normal *
1791 recv_values[i][q_index] +
1792 (penalty_constant / h_f) * recv_values[i][q_index] *
1793 recv_values[j][q_index]) *
1806 template <
int dim,
typename MatrixType>
1813 (std::is_same_v<MatrixType, TrilinosWrappers::SparseMatrix> ||
1814 std::is_same_v<MatrixType,
1820 ExcMessage(
"FE type not supported."));
1823 constraints.
close();
1824 const double penalty_constant =
1828 .create_agglomeration_sparsity_pattern(dsp);
1829 system_matrix.reinit(dsp);
1836 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1837 std::vector<types::global_dof_index> local_dof_indices_neighbor(
1842 if (polytope->is_locally_owned())
1845 const auto &agglo_values = ah.
reinit(polytope);
1846 for (
unsigned int q_index : agglo_values.quadrature_point_indices())
1848 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1850 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
1852 cell_matrix(i, j) +=
1853 agglo_values.shape_grad(i, q_index) *
1854 agglo_values.shape_grad(j, q_index) *
1855 agglo_values.JxW(q_index);
1860 polytope->get_dof_indices(local_dof_indices);
1862 unsigned int n_faces = polytope->n_faces();
1863 const double h_f = polytope->diameter();
1864 for (
unsigned int f = 0; f < n_faces; ++f)
1866 if (polytope->at_boundary(f))
1869 const auto &fe_face = ah.
reinit(polytope, f);
1871 for (
unsigned int q_index :
1872 fe_face.quadrature_point_indices())
1875 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
1877 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
1879 cell_matrix(i, j) +=
1880 (-fe_face.shape_value(i, q_index) *
1881 fe_face.shape_grad(j, q_index) * normal -
1882 fe_face.shape_grad(i, q_index) * normal *
1883 fe_face.shape_value(j, q_index) +
1884 (penalty_constant / h_f) *
1885 fe_face.shape_value(i, q_index) *
1886 fe_face.shape_value(j, q_index)) *
1887 fe_face.JxW(q_index);
1894 const auto &neigh_polytope = polytope->neighbor(f);
1895 if (polytope->id() < neigh_polytope->id())
1898 polytope->neighbor_of_agglomerated_neighbor(f);
1899 Assert(neigh_polytope->neighbor(nofn)->id() ==
1901 ExcMessage(
"Mismatch."));
1903 polytope, neigh_polytope, f, nofn);
1904 const auto &fe_faces0 = fe_faces.first;
1905 if (neigh_polytope->is_locally_owned())
1908 const auto &fe_faces1 = fe_faces.second;
1923 neigh_polytope->get_dof_indices(
1924 local_dof_indices_neighbor);
1926 M11, local_dof_indices, system_matrix);
1930 local_dof_indices_neighbor,
1934 local_dof_indices_neighbor,
1938 M22, local_dof_indices_neighbor, system_matrix);
1945 neigh_polytope->subdomain_id();
1946 const auto &recv_jxws =
1948 .at({neigh_polytope->id(), nofn});
1949 const auto &recv_values =
1951 .at({neigh_polytope->id(), nofn});
1952 const auto &recv_gradients =
1954 .at({neigh_polytope->id(), nofn});
1975 neigh_polytope->get_dof_indices(
1976 local_dof_indices_neighbor);
1978 M11, local_dof_indices, system_matrix);
1982 local_dof_indices_neighbor,
1986 local_dof_indices_neighbor,
1990 M22, local_dof_indices_neighbor, system_matrix);
2010 template <
int dim,
typename MatrixType,
typename VectorType>
2013 VectorType &system_rhs,
2019 (std::is_same_v<MatrixType, TrilinosWrappers::SparseMatrix> ||
2020 std::is_same_v<MatrixType,
2025 "Implemented only for simplex meshes for the time being."));
2028 ExcNotImplemented());
2030 const double penalty_constant = .5 * fe_dg.
degree * (fe_dg.
degree + 1);
2032 constraints.
close();
2035 const IndexSet locally_relevant_dofs =
2044 locally_relevant_dofs);
2046 system_matrix.reinit(locally_owned_dofs,
2053 const unsigned int quadrature_degree = fe_dg.
degree + 1;
2084 std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
2089 if (cell->is_locally_owned())
2101 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2103 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
2105 cell_matrix(i, j) += fe_values.
shape_grad(i, q_index) *
2107 fe_values.
JxW(q_index);
2111 fe_values.
JxW(q_index);
2116 cell->get_dof_indices(local_dof_indices);
2118 for (
const auto f : cell->face_indices())
2120 const double extent1 =
2121 cell->measure() / cell->face(f)->measure();
2123 if (cell->face(f)->at_boundary())
2125 hf = (1. / extent1 + 1. / extent1);
2126 fe_faces0.
reinit(cell, f);
2129 for (
unsigned int q_index :
2132 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2134 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
2136 cell_matrix(i, j) +=
2143 (penalty_constant * hf) *
2146 fe_faces0.
JxW(q_index);
2155 const auto &neigh_cell = cell->neighbor(f);
2156 if (cell->global_active_cell_index() <
2157 neigh_cell->global_active_cell_index())
2159 const double extent2 =
2160 neigh_cell->measure() /
2161 neigh_cell->face(cell->neighbor_of_neighbor(f))
2163 hf = (1. / extent1 + 1. / extent2);
2164 fe_faces0.
reinit(cell, f);
2165 fe_faces1.
reinit(neigh_cell,
2166 cell->neighbor_of_neighbor(f));
2168 std::vector<types::global_dof_index>
2169 local_dof_indices_neighbor(dofs_per_cell);
2178 for (
unsigned int q_index :
2181 for (
unsigned int i = 0; i < dofs_per_cell; ++i)
2183 for (
unsigned int j = 0; j < dofs_per_cell; ++j)
2192 (penalty_constant * hf) *
2195 fe_faces0.
JxW(q_index);
2204 (penalty_constant * hf) *
2207 fe_faces1.
JxW(q_index);
2217 (penalty_constant * hf) *
2220 fe_faces1.
JxW(q_index);
2230 (penalty_constant * hf) *
2233 fe_faces1.
JxW(q_index);
2240 neigh_cell->get_dof_indices(local_dof_indices_neighbor);
2243 M11, local_dof_indices, system_matrix);
2247 local_dof_indices_neighbor,
2251 local_dof_indices_neighbor,
2255 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
MPI_Comm get_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)
MPI_Comm get_communicator() const
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
const std::vector< std::vector< typename Triangulation< dim >::active_cell_iterator > > & extract_agglomerates()
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)
std::tuple< std::vector< double >, std::vector< double >, std::vector< double >, double > compute_quality_metrics(const AgglomerationHandler< dim > &ah)
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)
::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
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