--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2023 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+// Check results of limit_p_level_difference on cells that
+// share edges but no faces in 3D.
+//
+// 3D: n_refinements: 1 n_refinements: 2
+// mesh: future FE: mesh: future FE:
+// +---+-+-+ +---+++++ +-+-+++++ +-+-+++++
+// | | | | | |2|2| | | +++++ |0|1+222+
+// | +-+-+ | 1 +-+-+ +-+-+++++ +-+-+222+
+// | | | | | |2|2| | | +++++ |0|1+222+
+// +---X-+-+ +---X-+-+ +-+-X++++ +-+-X++++
+// | | | | | | | |0|0|
+// | | | 0 | +-+-+ |-+-|
+// | | | | | | | |0|0|
+// +---+ +---+ +---+ +---+
+
+#include <deal.II/base/utilities.h>
+
+#include <deal.II/dofs/dof_handler.h>
+
+#include <deal.II/fe/fe_q.h>
+
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria.h>
+
+#include <deal.II/hp/fe_collection.h>
+#include <deal.II/hp/refinement.h>
+
+#include <deal.II/numerics/data_out.h>
+
+#include <fstream>
+
+#include "../tests.h"
+
+
+template <int dim>
+void
+write(const DoFHandler<dim> &dofh, const unsigned int n_refinements)
+{
+ const auto &tria = dofh.get_triangulation();
+
+ Vector<float> active_fe_indices(tria.n_active_cells());
+ for (const auto &cell : dofh.active_cell_iterators())
+ if (cell->is_locally_owned())
+ active_fe_indices(cell->active_cell_index()) = cell->active_fe_index();
+
+ Vector<float> future_fe_indices(tria.n_active_cells());
+ for (const auto &cell : dofh.active_cell_iterators())
+ if (cell->is_locally_owned())
+ future_fe_indices(cell->active_cell_index()) = cell->future_fe_index();
+
+ DataOut<dim> data_out;
+ data_out.attach_dof_handler(dofh);
+ data_out.add_data_vector(active_fe_indices, "active_fe_indices");
+ data_out.add_data_vector(future_fe_indices, "future_fe_indices");
+ data_out.build_patches();
+
+ std::ofstream ofile("fe_indices-" + Utilities::to_string(dim) + "D-nref" +
+ Utilities::to_string(n_refinements) + ".vtk");
+ data_out.write_vtk(ofile);
+}
+
+
+template <int dim>
+void
+test(const unsigned int n_refinements)
+{
+ hp::FECollection<dim> fes;
+ for (unsigned int p = 1; p <= 3; ++p)
+ fes.push_back(FE_Q<dim>(p));
+
+ Triangulation<dim> tria;
+ DoFHandler<dim> dofh(tria);
+ {
+ // create L-shaped mesh
+ std::vector<unsigned int> repetitions(dim);
+ Point<dim> bottom_left, top_right;
+ for (unsigned int d = 0; d < dim; ++d)
+ if (d < 2)
+ {
+ repetitions[d] = 2;
+ bottom_left[d] = -1.;
+ top_right[d] = 1.;
+ }
+ else
+ {
+ repetitions[d] = 1;
+ bottom_left[d] = 0.;
+ top_right[d] = 1.;
+ }
+
+ std::vector<int> cells_to_remove(dim, 1);
+ cells_to_remove[0] = -1;
+
+ GridGenerator::subdivided_hyper_L(
+ tria, repetitions, bottom_left, top_right, cells_to_remove);
+
+ // refine grid according to sketch above
+ for (unsigned int i = 0; i < n_refinements; ++i)
+ {
+ for (const auto &cell : dofh.active_cell_iterators())
+ if (cell->center()[0] > 0)
+ {
+ cell->set_refine_flag();
+ cell->set_active_fe_index(2);
+ }
+
+ tria.execute_coarsening_and_refinement();
+ }
+ }
+
+ dofh.distribute_dofs(fes);
+ hp::Refinement::limit_p_level_difference(dofh,
+ /*max_difference=*/1,
+ /*contains=*/0);
+
+ // output FE indices
+ for (const auto &cell : dofh.active_cell_iterators())
+ deallog << cell->id().to_string() << ": active:" << cell->active_fe_index()
+ << " future:" << cell->future_fe_index() << std::endl;
+
+#if false
+ write(dofh, n_refinements);
+#endif
+
+ deallog << "OK" << std::endl;
+}
+
+
+int
+main()
+{
+ initlog();
+
+ deallog.push("2d");
+ test<2>(1);
+ test<2>(2);
+ deallog.pop();
+ deallog.push("3d");
+ test<3>(1);
+ test<3>(2);
+ deallog.pop();
+}
--- /dev/null
+
+DEAL:2d::0_0:: active:0 future:0
+DEAL:2d::1_0:: active:0 future:1
+DEAL:2d::2_1:0: active:2 future:2
+DEAL:2d::2_1:1: active:2 future:2
+DEAL:2d::2_1:2: active:2 future:2
+DEAL:2d::2_1:3: active:2 future:2
+DEAL:2d::OK
+DEAL:2d::0_0:: active:0 future:0
+DEAL:2d::1_1:0: active:0 future:0
+DEAL:2d::1_1:1: active:0 future:1
+DEAL:2d::1_1:2: active:0 future:0
+DEAL:2d::1_1:3: active:0 future:1
+DEAL:2d::2_2:00: active:2 future:2
+DEAL:2d::2_2:01: active:2 future:2
+DEAL:2d::2_2:02: active:2 future:2
+DEAL:2d::2_2:03: active:2 future:2
+DEAL:2d::2_2:10: active:2 future:2
+DEAL:2d::2_2:11: active:2 future:2
+DEAL:2d::2_2:12: active:2 future:2
+DEAL:2d::2_2:13: active:2 future:2
+DEAL:2d::2_2:20: active:2 future:2
+DEAL:2d::2_2:21: active:2 future:2
+DEAL:2d::2_2:22: active:2 future:2
+DEAL:2d::2_2:23: active:2 future:2
+DEAL:2d::2_2:30: active:2 future:2
+DEAL:2d::2_2:31: active:2 future:2
+DEAL:2d::2_2:32: active:2 future:2
+DEAL:2d::2_2:33: active:2 future:2
+DEAL:2d::OK
+DEAL:3d::0_0:: active:0 future:0
+DEAL:3d::1_0:: active:0 future:1
+DEAL:3d::2_1:0: active:2 future:2
+DEAL:3d::2_1:1: active:2 future:2
+DEAL:3d::2_1:2: active:2 future:2
+DEAL:3d::2_1:3: active:2 future:2
+DEAL:3d::2_1:4: active:2 future:2
+DEAL:3d::2_1:5: active:2 future:2
+DEAL:3d::2_1:6: active:2 future:2
+DEAL:3d::2_1:7: active:2 future:2
+DEAL:3d::OK
+DEAL:3d::0_1:0: active:0 future:0
+DEAL:3d::0_1:1: active:0 future:0
+DEAL:3d::0_1:2: active:0 future:0
+DEAL:3d::0_1:3: active:0 future:0
+DEAL:3d::0_1:4: active:0 future:0
+DEAL:3d::0_1:5: active:0 future:0
+DEAL:3d::0_1:6: active:0 future:0
+DEAL:3d::0_1:7: active:0 future:0
+DEAL:3d::1_1:0: active:0 future:0
+DEAL:3d::1_1:1: active:0 future:1
+DEAL:3d::1_1:2: active:0 future:0
+DEAL:3d::1_1:3: active:0 future:1
+DEAL:3d::1_1:4: active:0 future:0
+DEAL:3d::1_1:5: active:0 future:1
+DEAL:3d::1_1:6: active:0 future:0
+DEAL:3d::1_1:7: active:0 future:1
+DEAL:3d::2_2:00: active:2 future:2
+DEAL:3d::2_2:01: active:2 future:2
+DEAL:3d::2_2:02: active:2 future:2
+DEAL:3d::2_2:03: active:2 future:2
+DEAL:3d::2_2:04: active:2 future:2
+DEAL:3d::2_2:05: active:2 future:2
+DEAL:3d::2_2:06: active:2 future:2
+DEAL:3d::2_2:07: active:2 future:2
+DEAL:3d::2_2:10: active:2 future:2
+DEAL:3d::2_2:11: active:2 future:2
+DEAL:3d::2_2:12: active:2 future:2
+DEAL:3d::2_2:13: active:2 future:2
+DEAL:3d::2_2:14: active:2 future:2
+DEAL:3d::2_2:15: active:2 future:2
+DEAL:3d::2_2:16: active:2 future:2
+DEAL:3d::2_2:17: active:2 future:2
+DEAL:3d::2_2:20: active:2 future:2
+DEAL:3d::2_2:21: active:2 future:2
+DEAL:3d::2_2:22: active:2 future:2
+DEAL:3d::2_2:23: active:2 future:2
+DEAL:3d::2_2:24: active:2 future:2
+DEAL:3d::2_2:25: active:2 future:2
+DEAL:3d::2_2:26: active:2 future:2
+DEAL:3d::2_2:27: active:2 future:2
+DEAL:3d::2_2:30: active:2 future:2
+DEAL:3d::2_2:31: active:2 future:2
+DEAL:3d::2_2:32: active:2 future:2
+DEAL:3d::2_2:33: active:2 future:2
+DEAL:3d::2_2:34: active:2 future:2
+DEAL:3d::2_2:35: active:2 future:2
+DEAL:3d::2_2:36: active:2 future:2
+DEAL:3d::2_2:37: active:2 future:2
+DEAL:3d::2_2:40: active:2 future:2
+DEAL:3d::2_2:41: active:2 future:2
+DEAL:3d::2_2:42: active:2 future:2
+DEAL:3d::2_2:43: active:2 future:2
+DEAL:3d::2_2:44: active:2 future:2
+DEAL:3d::2_2:45: active:2 future:2
+DEAL:3d::2_2:46: active:2 future:2
+DEAL:3d::2_2:47: active:2 future:2
+DEAL:3d::2_2:50: active:2 future:2
+DEAL:3d::2_2:51: active:2 future:2
+DEAL:3d::2_2:52: active:2 future:2
+DEAL:3d::2_2:53: active:2 future:2
+DEAL:3d::2_2:54: active:2 future:2
+DEAL:3d::2_2:55: active:2 future:2
+DEAL:3d::2_2:56: active:2 future:2
+DEAL:3d::2_2:57: active:2 future:2
+DEAL:3d::2_2:60: active:2 future:2
+DEAL:3d::2_2:61: active:2 future:2
+DEAL:3d::2_2:62: active:2 future:2
+DEAL:3d::2_2:63: active:2 future:2
+DEAL:3d::2_2:64: active:2 future:2
+DEAL:3d::2_2:65: active:2 future:2
+DEAL:3d::2_2:66: active:2 future:2
+DEAL:3d::2_2:67: active:2 future:2
+DEAL:3d::2_2:70: active:2 future:2
+DEAL:3d::2_2:71: active:2 future:2
+DEAL:3d::2_2:72: active:2 future:2
+DEAL:3d::2_2:73: active:2 future:2
+DEAL:3d::2_2:74: active:2 future:2
+DEAL:3d::2_2:75: active:2 future:2
+DEAL:3d::2_2:76: active:2 future:2
+DEAL:3d::2_2:77: active:2 future:2
+DEAL:3d::OK