From aa9b3054a98eba1160b743d05e43d7541032255b Mon Sep 17 00:00:00 2001
From: Felix Schindler <felix.schindler@wwu.de>
Date: Sat, 27 Jan 2018 23:14:23 +0100
Subject: [PATCH] [test.spaces] add RT

---
 dune/gdt/test/spaces/spaces_rt.cc | 535 ++++++++++++++++++++++++++++++
 1 file changed, 535 insertions(+)
 create mode 100644 dune/gdt/test/spaces/spaces_rt.cc

diff --git a/dune/gdt/test/spaces/spaces_rt.cc b/dune/gdt/test/spaces/spaces_rt.cc
new file mode 100644
index 000000000..e045da37f
--- /dev/null
+++ b/dune/gdt/test/spaces/spaces_rt.cc
@@ -0,0 +1,535 @@
+// This file is part of the dune-gdt project:
+//   https://github.com/dune-community/dune-gdt
+// Copyright 2010-2017 dune-gdt developers and contributors. All rights reserved.
+// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
+//      or  GPL-2.0+ (http://opensource.org/licenses/gpl-license)
+//          with "runtime exception" (http://www.dune-project.org/license.html)
+// Authors:
+//   Felix Schindler (2018)
+
+#include <dune/xt/common/test/main.hxx> // <- this one has to come first (includes the config.h)!
+
+#include <algorithm>
+#include <memory>
+#include <tuple>
+
+#include <dune/geometry/quadraturerules.hh>
+#include <dune/geometry/referenceelements.hh>
+#include <dune/geometry/refinement.hh>
+
+#include <dune/grid/common/rangegenerators.hh>
+
+#include <dune/xt/common/fvector.hh>
+#include <dune/xt/common/numeric_cast.hh>
+#include <dune/xt/grid/gridprovider/cube.hh>
+
+#include <dune/gdt/spaces/rt/default.hh>
+
+
+template <class GridLayerType, int p>
+struct RtSpace : public ::testing::Test
+{
+  static_assert(p == 0, "The space cannot handle higher orders (yet)!");
+  using SpaceType = Dune::GDT::RtSpace<GridLayerType, p>;
+  using D = typename SpaceType::DomainFieldType;
+  static const constexpr size_t d = SpaceType::dimDomain;
+
+  virtual std::shared_ptr<GridLayerType> grid_layer() = 0;
+
+  std::shared_ptr<SpaceType> space;
+
+  ~RtSpace() = default;
+
+  void SetUp() override final
+  {
+    ASSERT_NE(grid_layer(), nullptr);
+    space = std::shared_ptr<SpaceType>(new SpaceType(*grid_layer()));
+  }
+
+  void TearDown() override final
+  {
+    space.reset();
+  }
+
+  void basis_exists_on_each_element_with_correct_size()
+  {
+    ASSERT_NE(grid_layer(), nullptr);
+    ASSERT_NE(space, nullptr);
+    for (auto&& element : elements(*grid_layer())) {
+      const auto& reference_element = Dune::ReferenceElements<D, d>::general(element.geometry().type());
+      EXPECT_EQ(reference_element.size(1), space->base_function_set(element).size());
+    }
+  }
+
+  void basis_exists_on_each_element_with_correct_order()
+  {
+    ASSERT_NE(grid_layer(), nullptr);
+    ASSERT_NE(space, nullptr);
+    for (auto&& element : elements(*grid_layer()))
+      EXPECT_EQ(1, space->base_function_set(element).order());
+  }
+
+  void mapper_reports_correct_num_DoFs_on_each_element()
+  {
+    ASSERT_NE(grid_layer(), nullptr);
+    ASSERT_NE(space, nullptr);
+    for (auto&& element : elements(*grid_layer())) {
+      const auto& reference_element = Dune::ReferenceElements<D, d>::general(element.geometry().type());
+      EXPECT_EQ(reference_element.size(1), space->mapper().numDofs(element));
+    }
+  }
+
+  void mapper_reports_correct_max_num_DoFs()
+  {
+    ASSERT_NE(grid_layer(), nullptr);
+    ASSERT_NE(space, nullptr);
+    size_t max_num_dofs = 0;
+    for (auto&& element : elements(*grid_layer()))
+      max_num_dofs = std::max(max_num_dofs, space->mapper().numDofs(element));
+    EXPECT_LE(max_num_dofs, space->mapper().maxNumDofs());
+  }
+
+  void mapper_maps_correctly()
+  {
+    ASSERT_NE(grid_layer(), nullptr);
+    ASSERT_NE(space, nullptr);
+    // collect all global ids that are associated with a global lagrange point
+    std::map<Dune::FieldVector<D, d>, std::set<size_t>, Dune::XT::Common::FieldVectorLess>
+        global_intersection_centers_to_global_indices_map;
+    for (auto&& element : elements(*grid_layer())) {
+      const auto global_indices = space->mapper().globalIndices(element);
+      EXPECT_LE(space->mapper().numDofs(element), global_indices.size());
+      const auto intersection_to_DoF_map = space->local_DoF_indices(element);
+      EXPECT_EQ(intersection_to_DoF_map.size(), space->mapper().numDofs(element));
+      for (auto&& intersection : intersections(*grid_layer(), element)) {
+        const auto intersection_index = intersection.indexInInside();
+        const auto local_DoF_index = intersection_to_DoF_map[intersection_index];
+        const auto global_index = space->mapper().mapToGlobal(element, local_DoF_index);
+        EXPECT_EQ(global_indices[local_DoF_index], global_index);
+        global_intersection_centers_to_global_indices_map[intersection.geometry().center()].insert(global_index);
+      }
+    }
+    // check that all intersections have indeed one and only one global DoF id ...
+    std::set<size_t> global_DoF_indices;
+    for (const auto& entry : global_intersection_centers_to_global_indices_map) {
+      const auto global_DoF_indices_per_intersection = entry.second;
+      EXPECT_EQ(global_DoF_indices_per_intersection.size(), 1);
+      global_DoF_indices.insert(*(global_DoF_indices_per_intersection.begin()));
+    }
+    EXPECT_EQ(global_intersection_centers_to_global_indices_map.size(), global_DoF_indices.size());
+    // ... and that the numbering is consecutive
+    size_t count = 0;
+    for (const auto& global_DoF_id : global_DoF_indices) {
+      EXPECT_EQ(global_DoF_id, count);
+      ++count;
+    }
+    EXPECT_EQ(global_DoF_indices.size(), space->mapper().size());
+  } // ... mapper_maps_correctly(...)
+
+  void local_DoF_indices_exist_on_each_element_with_correct_size()
+  {
+    ASSERT_NE(grid_layer(), nullptr);
+    ASSERT_NE(space, nullptr);
+    for (auto&& element : elements(*grid_layer())) {
+      const auto& reference_element = Dune::ReferenceElements<D, d>::general(element.geometry().type());
+      EXPECT_EQ(reference_element.size(1), space->local_DoF_indices(element).size());
+    }
+  }
+
+  void basis_is_rt_basis()
+  {
+    ASSERT_NE(grid_layer(), nullptr);
+    ASSERT_NE(space, nullptr);
+    Dune::GDT::ZeroOrderScalarDiscontinuousMapper<GridLayerType> entity_indices(*grid_layer());
+    for (auto&& element : elements(*grid_layer())) {
+      const auto basis = space->base_function_set(element);
+      const auto intersection_to_DoF_index_map = space->local_DoF_indices(element);
+      for (auto&& intersection : intersections(*grid_layer(), element)) {
+        const auto xx_in_element_coordinates = intersection.geometry().center();
+        const auto xx_in_reference_element_coordinates = element.geometry().local(xx_in_element_coordinates);
+        const auto xx_in_reference_intersection_coordinates =
+            intersection.geometryInInside().local(xx_in_reference_element_coordinates);
+        const auto normal = intersection.integrationOuterNormal(xx_in_reference_intersection_coordinates);
+        const auto basis_values = basis.evaluate(xx_in_reference_element_coordinates);
+        const auto intersection_index = intersection.indexInInside();
+        const auto DoF_index = intersection_to_DoF_index_map[intersection_index];
+        double switch_ = 1;
+        if (intersection.neighbor()
+            && entity_indices.mapToGlobal(element, 0) < entity_indices.mapToGlobal(intersection.outside(), 0))
+          switch_ *= -1.;
+        for (size_t ii = 0; ii < basis.size(); ++ii)
+          EXPECT_TRUE(Dune::XT::Common::FloatCmp::eq(
+              (ii == DoF_index ? 1. : 0.) * switch_, basis_values[ii] * normal, 1e-14, 1e-14))
+              << "ii = " << ii << "\nDoF_index = " << DoF_index << "\nii == DoF_index ? 1. : 0. "
+              << (ii == DoF_index ? 1. : 0.) << "\nbasis_values[ii] * normal = " << basis_values[ii] * normal;
+      }
+    }
+  } // ... basis_is_rt_basis(...)
+
+  void basis_jacobians_seem_to_be_correct()
+  {
+    ASSERT_NE(grid_layer(), nullptr);
+    ASSERT_NE(space, nullptr);
+    ASSERT_TRUE(false) << "continue here";
+    //    for (auto&& element : elements(*grid_layer())) {
+    //      const auto& reference_element = Dune::ReferenceElements<D, d>::general(element.geometry().type());
+    //      const auto basis = space->base_function_set(element);
+    //      const double h = 1e-6;
+    //      for (const auto& quadrature_point : Dune::QuadratureRules<D, d>::rule(element.geometry().type(),
+    //      basis.order())) {
+    //        const auto& xx = quadrature_point.position();
+    //        const auto& J_inv_T = element.geometry().jacobianInverseTransposed(xx);
+    //        const auto jacobians = basis.jacobian(xx);
+    //        EXPECT_EQ(basis.size(), jacobians.size());
+    //        const auto values_xx = basis.evaluate(xx);
+    //        EXPECT_EQ(basis.size(), values_xx.size());
+    //        auto approximate_jacobians = jacobians;
+    //        // compute approximate partial derivatives
+    //        for (size_t dd = 0; dd < d; ++dd) {
+    //          // try to find a suitable x + h
+    //          auto xx_plus_h = xx;
+    //          xx_plus_h[dd] += h;
+    //          if (!reference_element.checkInside(xx_plus_h)) {
+    //            xx_plus_h[dd] -= 2. * h;
+    //          }
+    //          ASSERT_TRUE(reference_element.checkInside(xx_plus_h)) << "xx_plus_h = " << xx_plus_h
+    //                                                                << " is not inside the reference element!";
+    //          const auto values_xx_plus_h = basis.evaluate(xx_plus_h);
+    //          EXPECT_EQ(basis.size(), values_xx_plus_h.size());
+    //          for (size_t ii = 0; ii < basis.size(); ++ii) {
+    //            approximate_jacobians[ii][0][dd] = (values_xx_plus_h[ii] - values_xx[ii]) / (xx_plus_h[dd] - xx[dd]);
+    //            if (xx_plus_h[dd] - xx[dd] < 0)
+    //              approximate_jacobians[ii][0][dd] *= -1.;
+    //          }
+    //        }
+    //        // transform
+    //        auto tmp_jac = approximate_jacobians[0][0];
+    //        for (size_t ii = 0; ii < basis.size(); ++ii) {
+    //          J_inv_T.mv(approximate_jacobians[ii][0], tmp_jac);
+    //          approximate_jacobians[ii][0] = tmp_jac;
+    //        }
+    //        // check
+    //        for (size_t ii = 0; ii < basis.size(); ++ii)
+    //          EXPECT_TRUE(Dune::XT::Common::FloatCmp::eq(jacobians[ii][0], approximate_jacobians[ii][0], 1e-4, 1e-4))
+    //              << "ii = " << ii << "\njacobians[ii][0] = " << jacobians[ii][0] << "\n"
+    //              << "approximate_jacobians[ii][0] = " << approximate_jacobians[ii][0] << "\n"
+    //              << "absolue L_infty error: " << (jacobians[ii][0] - approximate_jacobians[ii][0]).infinity_norm() <<
+    //              "\n"
+    //              << "relative L_infty error: "
+    //              << (jacobians[ii][0] - approximate_jacobians[ii][0]).infinity_norm() /
+    //              jacobians[ii][0].infinity_norm();
+    //      }
+    //    }
+  } // ... basis_jacobians_seem_to_be_correct(...)
+}; // struct RtSpace
+
+
+template <class G, int p>
+struct RtSpaceOnSimplicialLeafView : public RtSpace<typename Dune::XT::Grid::GridProvider<G>::LeafGridViewType, p>
+{
+  using GridProviderType = Dune::XT::Grid::GridProvider<G>;
+  using LeafGridViewType = typename GridProviderType::LeafGridViewType;
+
+  GridProviderType grid_provider;
+  std::shared_ptr<LeafGridViewType> leaf_view;
+
+  RtSpaceOnSimplicialLeafView() //        (i) negative coordinates and not the same as the reference
+      : grid_provider(Dune::XT::Grid::make_cube_grid<G>(-1.5, -1, 3).grid_ptr()) //                          element,
+  { //                                                   (ii) at least 3 elements to have fully inner ones,
+    grid_provider.global_refine(1); //                  (iii) refine at least once to obtain all kinds of orientations
+    leaf_view = std::make_shared<LeafGridViewType>(grid_provider.leaf_view());
+  }
+
+  ~RtSpaceOnSimplicialLeafView() = default;
+
+  std::shared_ptr<LeafGridViewType> grid_layer() override final
+  {
+    return leaf_view;
+  }
+}; // struct RtSpaceOnSimplicialLeafView
+
+
+using SimplicialGrids = ::testing::Types<ONED_1D,
+                                         YASP_1D_EQUIDISTANT_OFFSET
+#if HAVE_DUNE_ALUGRID
+                                         ,
+                                         ALU_2D_SIMPLEX_CONFORMING,
+                                         ALU_2D_SIMPLEX_NONCONFORMING
+#endif
+// UG does not work until we have the virtual interfaces for the finite elements.
+//#if HAVE_DUNE_UGGRID || HAVE_UG
+//                                         ,
+//                                         UG_2D
+//#endif
+#if HAVE_DUNE_ALUGRID
+                                         ,
+                                         ALU_3D_SIMPLEX_CONFORMING,
+                                         ALU_3D_SIMPLEX_NONCONFORMING
+#endif
+                                         // s.a.
+                                         //#if HAVE_DUNE_UGGRID || HAVE_UG
+                                         //                                         ,
+                                         //                                         UG_3D
+                                         //#endif
+                                         >;
+
+
+template <class G>
+using Order0SimplicialRtSpace = RtSpaceOnSimplicialLeafView<G, 0>;
+TYPED_TEST_CASE(Order0SimplicialRtSpace, SimplicialGrids);
+TYPED_TEST(Order0SimplicialRtSpace, basis_exists_on_each_element_with_correct_size)
+{
+  this->basis_exists_on_each_element_with_correct_size();
+}
+TYPED_TEST(Order0SimplicialRtSpace, basis_exists_on_each_element_with_correct_order)
+{
+  this->basis_exists_on_each_element_with_correct_order();
+}
+TYPED_TEST(Order0SimplicialRtSpace, mapper_reports_correct_num_DoFs_on_each_element)
+{
+  this->mapper_reports_correct_num_DoFs_on_each_element();
+}
+TYPED_TEST(Order0SimplicialRtSpace, mapper_reports_correct_max_num_DoFs)
+{
+  this->mapper_reports_correct_max_num_DoFs();
+}
+TYPED_TEST(Order0SimplicialRtSpace, mapper_maps_correctly)
+{
+  this->mapper_maps_correctly();
+}
+TYPED_TEST(Order0SimplicialRtSpace, local_DoF_indices_exist_on_each_element_with_correct_size)
+{
+  this->local_DoF_indices_exist_on_each_element_with_correct_size();
+}
+TYPED_TEST(Order0SimplicialRtSpace, basis_is_rt_basis)
+{
+  this->basis_is_rt_basis();
+}
+// TYPED_TEST(Order0SimplicialRtSpace, basis_jacobians_seem_to_be_correct)
+//{
+//  this->basis_jacobians_seem_to_be_correct();
+//}
+
+
+template <class G, int p>
+struct RtSpaceOnCubicLeafView : public RtSpace<typename Dune::XT::Grid::GridProvider<G>::LeafGridViewType, p>
+{
+  using GridProviderType = Dune::XT::Grid::GridProvider<G>;
+  using LeafGridViewType = typename GridProviderType::LeafGridViewType;
+
+  std::shared_ptr<GridProviderType> grid_provider;
+  std::shared_ptr<LeafGridViewType> leaf_view;
+
+  RtSpaceOnCubicLeafView()
+  {
+    using D = typename G::ctype;
+    static const constexpr size_t d = G::dimension;
+    Dune::FieldVector<D, d> lower_left(-1.5); //  (i) negative coordinates and not the same as the reference element
+    Dune::FieldVector<D, d> upper_right(-1.);
+    std::array<unsigned int, d> num_elements; // (ii) at least 3 elements to have fully inner ones
+    std::fill(num_elements.begin(), num_elements.end(), 3);
+    grid_provider = std::make_shared<GridProviderType>(
+        Dune::StructuredGridFactory<G>::createCubeGrid(lower_left, upper_right, num_elements));
+    leaf_view = std::make_shared<LeafGridViewType>(grid_provider->leaf_view());
+  }
+
+  ~RtSpaceOnCubicLeafView() = default;
+
+  std::shared_ptr<LeafGridViewType> grid_layer() override final
+  {
+    return leaf_view;
+  }
+}; // struct RtSpaceOnCubicLeafView
+
+
+using CubicGrids = ::testing::Types<YASP_2D_EQUIDISTANT_OFFSET
+#if HAVE_DUNE_ALUGRID
+                                    ,
+                                    ALU_2D_CUBE
+#endif
+                                    //// s.a.
+                                    //#if HAVE_DUNE_UGGRID || HAVE_UG
+                                    //                                    ,
+                                    //                                    UG_2D
+                                    //#endif
+                                    ,
+                                    YASP_3D_EQUIDISTANT_OFFSET
+#if HAVE_DUNE_ALUGRID
+                                    ,
+                                    ALU_3D_CUBE
+#endif
+                                    //// s.a.
+                                    //#if HAVE_DUNE_UGGRID || HAVE_UG
+                                    //                                    ,
+                                    //                                    UG_3D
+                                    //#endif
+                                    >;
+
+template <class G>
+using Order0CubicRtSpace = RtSpaceOnCubicLeafView<G, 0>;
+TYPED_TEST_CASE(Order0CubicRtSpace, CubicGrids);
+TYPED_TEST(Order0CubicRtSpace, basis_exists_on_each_element_with_correct_size)
+{
+  this->basis_exists_on_each_element_with_correct_size();
+}
+TYPED_TEST(Order0CubicRtSpace, basis_exists_on_each_element_with_correct_order)
+{
+  this->basis_exists_on_each_element_with_correct_order();
+}
+TYPED_TEST(Order0CubicRtSpace, mapper_reports_correct_num_DoFs_on_each_element)
+{
+  this->mapper_reports_correct_num_DoFs_on_each_element();
+}
+TYPED_TEST(Order0CubicRtSpace, mapper_reports_correct_max_num_DoFs)
+{
+  this->mapper_reports_correct_max_num_DoFs();
+}
+TYPED_TEST(Order0CubicRtSpace, mapper_maps_correctly)
+{
+  this->mapper_maps_correctly();
+}
+TYPED_TEST(Order0CubicRtSpace, local_DoF_indices_exist_on_each_element_with_correct_size)
+{
+  this->local_DoF_indices_exist_on_each_element_with_correct_size();
+}
+TYPED_TEST(Order0CubicRtSpace, basis_is_rt_basis)
+{
+  this->basis_is_rt_basis();
+}
+// TYPED_TEST(Order0CubicRtSpace, basis_jacobians_seem_to_be_correct)
+//{
+//  this->basis_jacobians_seem_to_be_correct();
+//}
+
+
+//// The space cannot handle mixed views (yet)!
+// template <class G, int p>
+// struct RtSpaceOnMixedLeafView : public RtSpace<typename Dune::XT::Grid::GridProvider<G>::LeafGridViewType, p>
+//{
+//  using GridProviderType = Dune::XT::Grid::GridProvider<G>;
+//  using LeafGridViewType = typename GridProviderType::LeafGridViewType;
+
+//  std::shared_ptr<GridProviderType> grid_provider;
+//  std::shared_ptr<LeafGridViewType> leaf_view;
+
+//  RtSpaceOnMixedLeafView()
+//  {
+//    using D = typename G::ctype;
+//    static const constexpr size_t d = G::dimension;
+//    switch (d) {
+//      case 1: {
+//        // cannot use ASSERT_... in a ctor
+//        EXPECT_TRUE(false) << "Does not make sense in 1d (all cubes are simplices)!\n"
+//                           << "=> ALL OTHER TESTS WILL FAIL FOR THIS GRID!!!";
+//        grid_provider = nullptr;
+//        leaf_view = nullptr;
+//        break;
+//      }
+//      case 2: {
+//        Dune::GridFactory<G> factory;
+//        for (auto&& vertex : {Dune::XT::Common::FieldVector<D, d>({-1., -1.5}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1., -1.25}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1., -1.}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.5, -1.5}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.5, -1.25}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.5, -1.}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.75, -1.25})}) {
+//          factory.insertVertex(vertex);
+//        }
+//        factory.insertElement(Dune::GeometryType(Dune::GeometryType::cube, 2), {3, 0, 4, 1});
+//        factory.insertElement(Dune::GeometryType(Dune::GeometryType::cube, 2), {4, 1, 5, 2});
+//        factory.insertElement(Dune::GeometryType(Dune::GeometryType::simplex, 2), {4, 6, 3});
+//        factory.insertElement(Dune::GeometryType(Dune::GeometryType::simplex, 2), {4, 5, 6});
+//        grid_provider = std::make_shared<GridProviderType>(factory.createGrid());
+//        grid_provider->global_refine(1);
+//        leaf_view = std::make_shared<LeafGridViewType>(grid_provider->leaf_view());
+//        break;
+//      }
+//      case 3: {
+//        Dune::GridFactory<G> factory;
+//        for (auto&& vertex : {Dune::XT::Common::FieldVector<D, d>({-1., -1.5, -1.}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1., -1.25, -1.}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1., -1., -1.}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.5, -1.5, -1.}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.5, -1.25, -1.}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.5, -1., -1.}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1., -1.5, -1.5}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1., -1.25, -1.5}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1., -1., -1.5}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.5, -1.5, -1.5}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.5, -1.25, -1.5}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.5, -1., -1.5}),
+//                              Dune::XT::Common::FieldVector<D, d>({-1.75, -1.25, -1.})}) {
+//          factory.insertVertex(vertex);
+//        }
+//        factory.insertElement(Dune::GeometryType(Dune::GeometryType::cube, 3), {3, 0, 4, 1, 9, 6, 10, 7});
+//        factory.insertElement(Dune::GeometryType(Dune::GeometryType::cube, 3), {4, 1, 5, 2, 10, 7, 11, 8});
+//        factory.insertElement(Dune::GeometryType(Dune::GeometryType::simplex, 3), {4, 12, 3, 10});
+//        factory.insertElement(Dune::GeometryType(Dune::GeometryType::simplex, 3), {4, 5, 12, 10});
+//        grid_provider = std::make_shared<GridProviderType>(factory.createGrid());
+//        grid_provider->global_refine(1);
+//        leaf_view = std::make_shared<LeafGridViewType>(grid_provider->leaf_view());
+//        break;
+//      }
+//      default: {
+//        // cannot use ASSERT_... in a ctor
+//        EXPECT_TRUE(false) << "Not implemented yet for dimension " << d << "!\n"
+//                           << "=> ALL OTHER TESTS WILL FAIL FOR THIS GRID!!!";
+//        grid_provider = nullptr;
+//        leaf_view = nullptr;
+//      }
+//    }
+//  } // RtSpaceOnMixedLeafView(...)
+
+//  ~RtSpaceOnMixedLeafView() = default;
+
+//  std::shared_ptr<LeafGridViewType> grid_layer() override final
+//  {
+//    return leaf_view;
+//  }
+//}; // struct RtSpaceOnMixedLeafView
+
+
+// using MixedGrids = ::testing::Types<
+//#ifHAVE_DUNE_UGGRID || HAVE_UG
+//    UG_2D,
+//    UG_3D
+//#endif
+//    >;
+
+
+// template <class G>
+// using Order0MixedRtSpace = RtSpaceOnMixedLeafView<G, 0>;
+// TYPED_TEST_CASE(Order0MixedRtSpace, MixedGrids);
+// TYPED_TEST(Order0MixedRtSpace, basis_exists_on_each_element_with_correct_size)
+//{
+//  this->basis_exists_on_each_element_with_correct_size();
+//}
+// TYPED_TEST(Order0MixedRtSpace, basis_exists_on_each_element_with_correct_order)
+//{
+//  this->basis_exists_on_each_element_with_correct_order();
+//}
+// TYPED_TEST(Order0MixedRtSpace, mapper_reports_correct_num_DoFs_on_each_element)
+//{
+//  this->mapper_reports_correct_num_DoFs_on_each_element();
+//}
+// TYPED_TEST(Order0MixedRtSpace, mapper_reports_correct_max_num_DoFs)
+//{
+//  this->mapper_reports_correct_max_num_DoFs();
+//}
+// TYPED_TEST(Order0MixedRtSpace, mapper_maps_correctly)
+//{
+//  this->mapper_maps_correctly();
+//}
+// TYPED_TEST(Order0MixedRtSpace, local_DoF_indices_exist_on_each_element_with_correct_size)
+//{
+//  this->local_DoF_indices_exist_on_each_element_with_correct_size();
+//}
+// TYPED_TEST(Order0MixedRtSpace, basis_is_rt_basis)
+//{
+//  this->basis_is_rt_basis();
+//}
+// TYPED_TEST(Order0MixedRtSpace, basis_jacobians_seem_to_be_correct)
+//{
+//  this->basis_jacobians_seem_to_be_correct();
+//}
-- 
GitLab