]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Extend QProjector for simplex 10722/head
authorPeter Munch <peterrmuench@gmail.com>
Sun, 19 Jul 2020 15:43:58 +0000 (17:43 +0200)
committerPeter Munch <peterrmuench@gmail.com>
Wed, 22 Jul 2020 19:25:36 +0000 (21:25 +0200)
source/base/qprojector.cc
tests/simplex/q_projection_01.cc [new file with mode: 0644]
tests/simplex/q_projection_01.output [new file with mode: 0644]

index 275a9356be0219ff009a50b113f80e3ef998cf89..ccd41a6745c50243e5d370cf6e6698b330ab5f29 100644 (file)
 //
 // ---------------------------------------------------------------------
 
+#include <deal.II/base/derivative_form.h>
 #include <deal.II/base/geometry_info.h>
 #include <deal.II/base/qprojector.h>
 
+#include <deal.II/simplex/polynomials.h>
+
 DEAL_II_NAMESPACE_OPEN
 
 
@@ -519,8 +522,70 @@ QProjector<2>::project_to_all_faces(
   const ReferenceCell::Type reference_cell_type,
   const SubQuadrature &     quadrature)
 {
+  if (reference_cell_type == ReferenceCell::Type::Tri)
+    {
+      // the quadrature rule to be projected ...
+      const auto &sub_quadrature_points  = quadrature.get_points();
+      const auto &sub_quadrature_weights = quadrature.get_weights();
+
+      // ... on to the faces (defined by its support points and arc length)
+      const std::array<std::pair<std::array<Point<2>, 2>, double>, 3> faces = {
+        {{{Point<2>(0.0, 0.0), Point<2>(1.0, 0.0)}, 1.0},
+         {{Point<2>(1.0, 0.0), Point<2>(0.0, 1.0)}, std::sqrt(2.0)},
+         {{Point<2>(0.0, 1.0), Point<2>(0.0, 0.0)}, 1.0}}};
+
+      // linear polynomial to map the reference quadrature points correctly
+      // on faces
+      const Simplex::ScalarPolynomial<1> poly(1);
+
+      // new (projected) quadrature points and weights
+      std::vector<Point<2>> points;
+      std::vector<double>   weights;
+
+      // loop over all faces (lines) ...
+      for (const auto &face : faces)
+        // ... and over all possible orientations
+        for (unsigned int orientation = 0; orientation < 2; ++orientation)
+          {
+            std::array<Point<2>, 2> support_points;
+
+            // determine support point of the current line with the correct
+            // orientation
+            switch (orientation)
+              {
+                case 0:
+                  support_points = {face.first[1], face.first[0]};
+                  break;
+                case 1:
+                  support_points = {face.first[0], face.first[1]};
+                  break;
+                default:
+                  Assert(false, ExcNotImplemented());
+              }
+
+            // loop over all quadrature points
+            for (unsigned int j = 0; j < sub_quadrature_points.size(); ++j)
+              {
+                Point<2> mapped_point;
+
+                // map reference quadrature point
+                for (unsigned int i = 0; i < 2; ++i)
+                  mapped_point +=
+                    support_points[i] *
+                    poly.compute_value(i, sub_quadrature_points[j]);
+
+                points.emplace_back(mapped_point);
+
+                // scale weight by arc length
+                weights.emplace_back(sub_quadrature_weights[j] * face.second);
+              }
+          }
+
+      // construct new quadrature rule
+      return {points, weights};
+    }
+
   Assert(reference_cell_type == ReferenceCell::Type::Quad, ExcNotImplemented());
-  (void)reference_cell_type;
 
   const unsigned int dim = 2;
 
@@ -571,8 +636,154 @@ QProjector<3>::project_to_all_faces(
   const ReferenceCell::Type reference_cell_type,
   const SubQuadrature &     quadrature)
 {
+  if (reference_cell_type == ReferenceCell::Type::Tet)
+    {
+      // the quadrature rule to be projected ...
+      const auto &sub_quadrature_points  = quadrature.get_points();
+      const auto &sub_quadrature_weights = quadrature.get_weights();
+
+      // ... on to the faces (defined by its support points and its area)
+      // note: the area is later not used as a scaling factor but recomputed
+      const std::array<std::pair<std::array<Point<3>, 3>, double>, 4> faces = {
+        {{{Point<3>(0.0, 0.0, 0.0),
+           Point<3>(1.0, 0.0, 0.0),
+           Point<3>(0.0, 1.0, 0.0)},
+          0.5},
+         {{Point<3>(1.0, 0.0, 0.0),
+           Point<3>(0.0, 0.0, 0.0),
+           Point<3>(0.0, 0.0, 1.0)},
+          0.5},
+         {{Point<3>(0.0, 0.0, 0.0),
+           Point<3>(0.0, 1.0, 0.0),
+           Point<3>(0.0, 0.0, 1.0)},
+          0.5},
+         {{Point<3>(0.0, 1.0, 0.0),
+           Point<3>(1.0, 0.0, 0.0),
+           Point<3>(0.0, 0.0, 1.0)},
+          0.5 * sqrt(3.0) /*equilateral triangle*/}}};
+
+      // linear polynomial to map the reference quadrature points correctly
+      // on faces
+      const Simplex::ScalarPolynomial<2> poly(1);
+
+      // new (projected) quadrature points and weights
+      std::vector<Point<3>> points;
+      std::vector<double>   weights;
+
+      // loop over all faces (triangles) ...
+      for (const auto &face : faces)
+        // ... and over all possible orientations
+        for (unsigned int orientation = 0; orientation < 6; ++orientation)
+          {
+            std::array<Point<3>, 3> support_points;
+
+            // determine support point of the current line with the correct
+            // orientation
+            switch (orientation)
+              {
+                case 1:
+                  support_points = {face.first[0],
+                                    face.first[1],
+                                    face.first[2]};
+                  break;
+                case 3:
+                  support_points = {face.first[1],
+                                    face.first[0],
+                                    face.first[2]};
+                  break;
+                case 5:
+                  support_points = {face.first[2],
+                                    face.first[0],
+                                    face.first[1]};
+                  break;
+                case 0:
+                  support_points = {face.first[0],
+                                    face.first[2],
+                                    face.first[1]};
+                  break;
+                case 2:
+                  support_points = {face.first[1],
+                                    face.first[2],
+                                    face.first[0]};
+                  break;
+                case 4:
+                  support_points = {face.first[2],
+                                    face.first[1],
+                                    face.first[0]};
+                  break;
+                default:
+                  Assert(false, ExcNotImplemented());
+              }
+
+            // loop over all quadrature points
+            for (unsigned int j = 0; j < sub_quadrature_points.size(); ++j)
+              {
+                Point<3> mapped_point;
+
+                // map reference quadrature point
+                for (unsigned int i = 0; i < 3; ++i)
+                  mapped_point +=
+                    support_points[i] *
+                    poly.compute_value(i, sub_quadrature_points[j]);
+
+                points.push_back(mapped_point);
+
+                // scale quadrature weight
+                const double scaling = [&]() {
+                  const auto &supp_pts = support_points;
+
+                  const unsigned int n_shape_functions = 3;
+                  const unsigned int dim_              = 2;
+                  const unsigned int spacedim          = 3;
+
+                  double result[spacedim][dim_];
+
+                  std::vector<Tensor<1, dim_>> shape_derivatives(
+                    n_shape_functions);
+
+                  for (unsigned int i = 0; i < 3; ++i)
+                    shape_derivatives[i] =
+                      poly.compute_1st_derivative(i, sub_quadrature_points[j]);
+
+                  for (unsigned int i = 0; i < spacedim; ++i)
+                    for (unsigned int j = 0; j < dim_; ++j)
+                      result[i][j] = shape_derivatives[0][j] * supp_pts[0][i];
+                  for (unsigned int k = 1; k < n_shape_functions; ++k)
+                    for (unsigned int i = 0; i < spacedim; ++i)
+                      for (unsigned int j = 0; j < dim_; ++j)
+                        result[i][j] +=
+                          shape_derivatives[k][j] * supp_pts[k][i];
+
+                  DerivativeForm<1, dim_, spacedim> contravariant;
+
+                  for (unsigned int i = 0; i < spacedim; ++i)
+                    for (unsigned int j = 0; j < dim_; ++j)
+                      contravariant[i][j] = result[i][j];
+
+
+                  Tensor<1, spacedim> DX_t[dim_];
+                  for (unsigned int i = 0; i < spacedim; ++i)
+                    for (unsigned int j = 0; j < dim_; ++j)
+                      DX_t[j][i] = contravariant[i][j];
+
+                  Tensor<2, dim_> G;
+                  for (unsigned int i = 0; i < dim_; ++i)
+                    for (unsigned int j = 0; j < dim_; ++j)
+                      G[i][j] = DX_t[i] * DX_t[j];
+
+                  return std::sqrt(determinant(G));
+                }();
+
+                weights.push_back(sub_quadrature_weights[j] * scaling);
+              }
+          }
+
+      // construct new quadrature rule
+      return {points, weights};
+    }
+
+
   Assert(reference_cell_type == ReferenceCell::Type::Hex, ExcNotImplemented());
-  (void)reference_cell_type;
 
   const unsigned int dim = 3;
 
@@ -996,9 +1207,21 @@ QProjector<dim>::DataSetDescriptor::face(
   const bool                face_rotation,
   const unsigned int        n_quadrature_points)
 {
+  if (reference_cell_type == ReferenceCell::Type::Tri ||
+      reference_cell_type == ReferenceCell::Type::Tet)
+    {
+      if (dim == 2)
+        return {(2 * face_no + face_orientation) * n_quadrature_points};
+      else if (dim == 3)
+        {
+          const unsigned int orientation =
+            (face_flip * 2 + face_rotation) * 2 + face_orientation;
+          return {(6 * face_no + orientation) * n_quadrature_points};
+        }
+    }
+
   Assert(reference_cell_type == ReferenceCell::get_hypercube(dim),
          ExcNotImplemented());
-  (void)reference_cell_type;
 
   Assert(face_no < GeometryInfo<dim>::faces_per_cell, ExcInternalError());
 
diff --git a/tests/simplex/q_projection_01.cc b/tests/simplex/q_projection_01.cc
new file mode 100644 (file)
index 0000000..919c388
--- /dev/null
@@ -0,0 +1,163 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2020 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.
+//
+// ---------------------------------------------------------------------
+
+
+// Test QProjection for Simplex::PGauss.
+
+
+#include <deal.II/base/qprojector.h>
+
+#include <deal.II/simplex/quadrature_lib.h>
+
+#include "../tests.h"
+
+using namespace dealii;
+
+template <int dim>
+void
+test(const unsigned int)
+{
+  AssertThrow(false, ExcNotImplemented())
+}
+
+template <>
+void
+test<2>(const unsigned int n_points)
+{
+  const int dim = 2;
+
+  Simplex::PGauss<dim - 1> quad_ref(n_points);
+
+  const auto quad =
+    QProjector<dim>::project_to_all_faces(ReferenceCell::Type::Tri, quad_ref);
+
+  const auto print = [&](const unsigned int face_no,
+                         const bool         face_orientation) {
+    deallog << "face_no=" << face_no
+            << " face_orientation=" << (face_orientation ? "true" : "false")
+            << ":" << std::endl;
+    for (unsigned int
+           q = 0,
+           i =
+             QProjector<dim>::DataSetDescriptor::face(ReferenceCell::Type::Tri,
+                                                      face_no,
+                                                      face_orientation,
+                                                      false,
+                                                      false,
+                                                      n_points);
+         q < n_points;
+         ++q, ++i)
+      {
+        deallog << quad.point(i) << " ";
+        deallog << quad.weight(i) << " ";
+        deallog << std::endl;
+      }
+    deallog << std::endl;
+  };
+
+  for (unsigned int i = 0; i < 3; ++i)
+    {
+      print(i, true);  // 1
+      print(i, false); // 0
+    }
+}
+
+template <>
+void
+test<3>(const unsigned int n_points)
+{
+  const int dim = 3;
+
+  Simplex::PGauss<dim - 1> quad_ref(n_points);
+
+  const auto quad =
+    QProjector<dim>::project_to_all_faces(ReferenceCell::Type::Tet, quad_ref);
+
+  const auto print = [&](const unsigned int face_no,
+                         const bool         face_orientation,
+                         const bool         face_flip,
+                         const bool         face_rotation) {
+    deallog << "face_no=" << face_no
+            << " face_orientation=" << (face_orientation ? "true" : "false")
+            << " face_flip=" << (face_flip ? "true" : "false")
+            << " face_rotation=" << (face_rotation ? "true" : "false") << ":"
+            << std::endl;
+    for (unsigned int
+           q = 0,
+           i =
+             QProjector<dim>::DataSetDescriptor::face(ReferenceCell::Type::Tet,
+                                                      face_no,
+                                                      face_orientation,
+                                                      face_flip,
+                                                      face_rotation,
+                                                      n_points);
+         q < n_points;
+         ++q, ++i)
+      {
+        deallog << quad.point(i) << " ";
+        deallog << quad.weight(i) << " ";
+        deallog << std::endl;
+      }
+    deallog << std::endl;
+  };
+
+  for (unsigned int i = 0; i < 4; ++i)
+    {
+      print(i, true, false, false);  // 1
+      print(i, true, true, false);   // 3
+      print(i, true, false, true);   // 5
+      print(i, false, false, false); // 0
+      print(i, false, true, false);  // 2
+      print(i, false, false, true);  // 4
+    }
+}
+
+int
+main()
+{
+  initlog();
+
+  {
+    deallog.push("2d-1");
+    test<2>(1);
+    deallog.pop();
+  }
+  {
+    deallog.push("2d-2");
+    test<2>(2);
+    deallog.pop();
+  }
+  {
+    deallog.push("2d-3");
+    test<2>(3);
+    deallog.pop();
+  }
+
+  {
+    deallog.push("3d-1");
+    test<3>(1);
+    deallog.pop();
+  }
+  {
+    deallog.push("3d-4");
+    test<3>(3);
+    deallog.pop();
+  }
+  {
+    deallog.push("3d-10");
+    test<3>(7);
+    deallog.pop();
+  }
+}
diff --git a/tests/simplex/q_projection_01.output b/tests/simplex/q_projection_01.output
new file mode 100644 (file)
index 0000000..862e421
--- /dev/null
@@ -0,0 +1,481 @@
+
+DEAL:2d-1::face_no=0 face_orientation=true:
+DEAL:2d-1::0.500000 0.00000 1.00000 
+DEAL:2d-1::
+DEAL:2d-1::face_no=0 face_orientation=false:
+DEAL:2d-1::0.500000 0.00000 1.00000 
+DEAL:2d-1::
+DEAL:2d-1::face_no=1 face_orientation=true:
+DEAL:2d-1::0.500000 0.500000 1.41421 
+DEAL:2d-1::
+DEAL:2d-1::face_no=1 face_orientation=false:
+DEAL:2d-1::0.500000 0.500000 1.41421 
+DEAL:2d-1::
+DEAL:2d-1::face_no=2 face_orientation=true:
+DEAL:2d-1::0.00000 0.500000 1.00000 
+DEAL:2d-1::
+DEAL:2d-1::face_no=2 face_orientation=false:
+DEAL:2d-1::0.00000 0.500000 1.00000 
+DEAL:2d-1::
+DEAL:2d-2::face_no=0 face_orientation=true:
+DEAL:2d-2::0.211325 0.00000 0.500000 
+DEAL:2d-2::0.788675 0.00000 0.500000 
+DEAL:2d-2::
+DEAL:2d-2::face_no=0 face_orientation=false:
+DEAL:2d-2::0.788675 0.00000 0.500000 
+DEAL:2d-2::0.211325 0.00000 0.500000 
+DEAL:2d-2::
+DEAL:2d-2::face_no=1 face_orientation=true:
+DEAL:2d-2::0.788675 0.211325 0.707107 
+DEAL:2d-2::0.211325 0.788675 0.707107 
+DEAL:2d-2::
+DEAL:2d-2::face_no=1 face_orientation=false:
+DEAL:2d-2::0.211325 0.788675 0.707107 
+DEAL:2d-2::0.788675 0.211325 0.707107 
+DEAL:2d-2::
+DEAL:2d-2::face_no=2 face_orientation=true:
+DEAL:2d-2::0.00000 0.788675 0.500000 
+DEAL:2d-2::0.00000 0.211325 0.500000 
+DEAL:2d-2::
+DEAL:2d-2::face_no=2 face_orientation=false:
+DEAL:2d-2::0.00000 0.211325 0.500000 
+DEAL:2d-2::0.00000 0.788675 0.500000 
+DEAL:2d-2::
+DEAL:2d-3::face_no=0 face_orientation=true:
+DEAL:2d-3::0.112702 0.00000 0.277778 
+DEAL:2d-3::0.500000 0.00000 0.444444 
+DEAL:2d-3::0.887298 0.00000 0.277778 
+DEAL:2d-3::
+DEAL:2d-3::face_no=0 face_orientation=false:
+DEAL:2d-3::0.887298 0.00000 0.277778 
+DEAL:2d-3::0.500000 0.00000 0.444444 
+DEAL:2d-3::0.112702 0.00000 0.277778 
+DEAL:2d-3::
+DEAL:2d-3::face_no=1 face_orientation=true:
+DEAL:2d-3::0.887298 0.112702 0.392837 
+DEAL:2d-3::0.500000 0.500000 0.628539 
+DEAL:2d-3::0.112702 0.887298 0.392837 
+DEAL:2d-3::
+DEAL:2d-3::face_no=1 face_orientation=false:
+DEAL:2d-3::0.112702 0.887298 0.392837 
+DEAL:2d-3::0.500000 0.500000 0.628539 
+DEAL:2d-3::0.887298 0.112702 0.392837 
+DEAL:2d-3::
+DEAL:2d-3::face_no=2 face_orientation=true:
+DEAL:2d-3::0.00000 0.887298 0.277778 
+DEAL:2d-3::0.00000 0.500000 0.444444 
+DEAL:2d-3::0.00000 0.112702 0.277778 
+DEAL:2d-3::
+DEAL:2d-3::face_no=2 face_orientation=false:
+DEAL:2d-3::0.00000 0.112702 0.277778 
+DEAL:2d-3::0.00000 0.500000 0.444444 
+DEAL:2d-3::0.00000 0.887298 0.277778 
+DEAL:2d-3::
+DEAL:3d-1::face_no=0 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-1::0.333333 0.333333 0.00000 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=0 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-1::0.333333 0.333333 0.00000 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=0 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-1::0.333333 0.333333 0.00000 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=0 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-1::0.333333 0.333333 0.00000 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=0 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-1::0.333333 0.333333 0.00000 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=0 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-1::0.333333 0.333333 0.00000 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=1 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-1::0.333333 0.00000 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=1 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-1::0.333333 0.00000 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=1 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-1::0.333333 0.00000 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=1 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-1::0.333333 0.00000 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=1 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-1::0.333333 0.00000 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=1 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-1::0.333333 0.00000 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=2 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-1::0.00000 0.333333 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=2 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-1::0.00000 0.333333 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=2 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-1::0.00000 0.333333 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=2 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-1::0.00000 0.333333 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=2 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-1::0.00000 0.333333 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=2 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-1::0.00000 0.333333 0.333333 1.00000 
+DEAL:3d-1::
+DEAL:3d-1::face_no=3 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-1::0.333333 0.333333 0.333333 1.73205 
+DEAL:3d-1::
+DEAL:3d-1::face_no=3 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-1::0.333333 0.333333 0.333333 1.73205 
+DEAL:3d-1::
+DEAL:3d-1::face_no=3 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-1::0.333333 0.333333 0.333333 1.73205 
+DEAL:3d-1::
+DEAL:3d-1::face_no=3 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-1::0.333333 0.333333 0.333333 1.73205 
+DEAL:3d-1::
+DEAL:3d-1::face_no=3 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-1::0.333333 0.333333 0.333333 1.73205 
+DEAL:3d-1::
+DEAL:3d-1::face_no=3 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-1::0.333333 0.333333 0.333333 1.73205 
+DEAL:3d-1::
+DEAL:3d-4::face_no=0 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-4::0.666667 0.166667 0.00000 0.166667 
+DEAL:3d-4::0.166667 0.666667 0.00000 0.166667 
+DEAL:3d-4::0.166667 0.166667 0.00000 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=0 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-4::0.166667 0.166667 0.00000 0.166667 
+DEAL:3d-4::0.666667 0.166667 0.00000 0.166667 
+DEAL:3d-4::0.166667 0.666667 0.00000 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=0 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-4::0.166667 0.166667 0.00000 0.166667 
+DEAL:3d-4::0.166667 0.666667 0.00000 0.166667 
+DEAL:3d-4::0.666667 0.166667 0.00000 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=0 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-4::0.166667 0.666667 0.00000 0.166667 
+DEAL:3d-4::0.666667 0.166667 0.00000 0.166667 
+DEAL:3d-4::0.166667 0.166667 0.00000 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=0 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-4::0.666667 0.166667 0.00000 0.166667 
+DEAL:3d-4::0.166667 0.166667 0.00000 0.166667 
+DEAL:3d-4::0.166667 0.666667 0.00000 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=0 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-4::0.166667 0.666667 0.00000 0.166667 
+DEAL:3d-4::0.166667 0.166667 0.00000 0.166667 
+DEAL:3d-4::0.666667 0.166667 0.00000 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=1 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-4::0.166667 0.00000 0.166667 0.166667 
+DEAL:3d-4::0.166667 0.00000 0.666667 0.166667 
+DEAL:3d-4::0.666667 0.00000 0.166667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=1 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-4::0.666667 0.00000 0.166667 0.166667 
+DEAL:3d-4::0.166667 0.00000 0.166667 0.166667 
+DEAL:3d-4::0.166667 0.00000 0.666667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=1 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-4::0.666667 0.00000 0.166667 0.166667 
+DEAL:3d-4::0.166667 0.00000 0.666667 0.166667 
+DEAL:3d-4::0.166667 0.00000 0.166667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=1 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-4::0.166667 0.00000 0.666667 0.166667 
+DEAL:3d-4::0.166667 0.00000 0.166667 0.166667 
+DEAL:3d-4::0.666667 0.00000 0.166667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=1 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-4::0.166667 0.00000 0.166667 0.166667 
+DEAL:3d-4::0.666667 0.00000 0.166667 0.166667 
+DEAL:3d-4::0.166667 0.00000 0.666667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=1 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-4::0.166667 0.00000 0.666667 0.166667 
+DEAL:3d-4::0.666667 0.00000 0.166667 0.166667 
+DEAL:3d-4::0.166667 0.00000 0.166667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=2 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-4::0.00000 0.666667 0.166667 0.166667 
+DEAL:3d-4::0.00000 0.166667 0.666667 0.166667 
+DEAL:3d-4::0.00000 0.166667 0.166667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=2 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-4::0.00000 0.166667 0.166667 0.166667 
+DEAL:3d-4::0.00000 0.666667 0.166667 0.166667 
+DEAL:3d-4::0.00000 0.166667 0.666667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=2 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-4::0.00000 0.166667 0.166667 0.166667 
+DEAL:3d-4::0.00000 0.166667 0.666667 0.166667 
+DEAL:3d-4::0.00000 0.666667 0.166667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=2 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-4::0.00000 0.166667 0.666667 0.166667 
+DEAL:3d-4::0.00000 0.666667 0.166667 0.166667 
+DEAL:3d-4::0.00000 0.166667 0.166667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=2 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-4::0.00000 0.666667 0.166667 0.166667 
+DEAL:3d-4::0.00000 0.166667 0.166667 0.166667 
+DEAL:3d-4::0.00000 0.166667 0.666667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=2 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-4::0.00000 0.166667 0.666667 0.166667 
+DEAL:3d-4::0.00000 0.166667 0.166667 0.166667 
+DEAL:3d-4::0.00000 0.666667 0.166667 0.166667 
+DEAL:3d-4::
+DEAL:3d-4::face_no=3 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-4::0.666667 0.166667 0.166667 0.288675 
+DEAL:3d-4::0.166667 0.166667 0.666667 0.288675 
+DEAL:3d-4::0.166667 0.666667 0.166667 0.288675 
+DEAL:3d-4::
+DEAL:3d-4::face_no=3 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-4::0.166667 0.666667 0.166667 0.288675 
+DEAL:3d-4::0.666667 0.166667 0.166667 0.288675 
+DEAL:3d-4::0.166667 0.166667 0.666667 0.288675 
+DEAL:3d-4::
+DEAL:3d-4::face_no=3 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-4::0.166667 0.666667 0.166667 0.288675 
+DEAL:3d-4::0.166667 0.166667 0.666667 0.288675 
+DEAL:3d-4::0.666667 0.166667 0.166667 0.288675 
+DEAL:3d-4::
+DEAL:3d-4::face_no=3 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-4::0.166667 0.166667 0.666667 0.288675 
+DEAL:3d-4::0.666667 0.166667 0.166667 0.288675 
+DEAL:3d-4::0.166667 0.666667 0.166667 0.288675 
+DEAL:3d-4::
+DEAL:3d-4::face_no=3 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-4::0.666667 0.166667 0.166667 0.288675 
+DEAL:3d-4::0.166667 0.666667 0.166667 0.288675 
+DEAL:3d-4::0.166667 0.166667 0.666667 0.288675 
+DEAL:3d-4::
+DEAL:3d-4::face_no=3 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-4::0.166667 0.166667 0.666667 0.288675 
+DEAL:3d-4::0.166667 0.666667 0.166667 0.288675 
+DEAL:3d-4::0.666667 0.166667 0.166667 0.288675 
+DEAL:3d-4::
+DEAL:3d-10::face_no=0 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-10::0.333333 0.333333 0.00000 0.112500 
+DEAL:3d-10::0.797427 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.101287 0.797427 0.00000 0.0629696 
+DEAL:3d-10::0.101287 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.0597159 0.470142 0.00000 0.0661971 
+DEAL:3d-10::0.470142 0.0597159 0.00000 0.0661971 
+DEAL:3d-10::0.470142 0.470142 0.00000 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=0 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-10::0.333333 0.333333 0.00000 0.112500 
+DEAL:3d-10::0.101287 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.797427 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.101287 0.797427 0.00000 0.0629696 
+DEAL:3d-10::0.470142 0.470142 0.00000 0.0661971 
+DEAL:3d-10::0.0597159 0.470142 0.00000 0.0661971 
+DEAL:3d-10::0.470142 0.0597159 0.00000 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=0 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-10::0.333333 0.333333 0.00000 0.112500 
+DEAL:3d-10::0.101287 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.101287 0.797427 0.00000 0.0629696 
+DEAL:3d-10::0.797427 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.470142 0.470142 0.00000 0.0661971 
+DEAL:3d-10::0.470142 0.0597159 0.00000 0.0661971 
+DEAL:3d-10::0.0597159 0.470142 0.00000 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=0 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-10::0.333333 0.333333 0.00000 0.112500 
+DEAL:3d-10::0.101287 0.797427 0.00000 0.0629696 
+DEAL:3d-10::0.797427 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.101287 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.470142 0.0597159 0.00000 0.0661971 
+DEAL:3d-10::0.0597159 0.470142 0.00000 0.0661971 
+DEAL:3d-10::0.470142 0.470142 0.00000 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=0 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-10::0.333333 0.333333 0.00000 0.112500 
+DEAL:3d-10::0.797427 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.101287 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.101287 0.797427 0.00000 0.0629696 
+DEAL:3d-10::0.0597159 0.470142 0.00000 0.0661971 
+DEAL:3d-10::0.470142 0.470142 0.00000 0.0661971 
+DEAL:3d-10::0.470142 0.0597159 0.00000 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=0 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-10::0.333333 0.333333 0.00000 0.112500 
+DEAL:3d-10::0.101287 0.797427 0.00000 0.0629696 
+DEAL:3d-10::0.101287 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.797427 0.101287 0.00000 0.0629696 
+DEAL:3d-10::0.470142 0.0597159 0.00000 0.0661971 
+DEAL:3d-10::0.470142 0.470142 0.00000 0.0661971 
+DEAL:3d-10::0.0597159 0.470142 0.00000 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=1 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-10::0.333333 0.00000 0.333333 0.112500 
+DEAL:3d-10::0.101287 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.101287 0.00000 0.797427 0.0629696 
+DEAL:3d-10::0.797427 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.470142 0.00000 0.470142 0.0661971 
+DEAL:3d-10::0.470142 0.00000 0.0597159 0.0661971 
+DEAL:3d-10::0.0597159 0.00000 0.470142 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=1 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-10::0.333333 0.00000 0.333333 0.112500 
+DEAL:3d-10::0.797427 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.101287 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.101287 0.00000 0.797427 0.0629696 
+DEAL:3d-10::0.0597159 0.00000 0.470142 0.0661971 
+DEAL:3d-10::0.470142 0.00000 0.470142 0.0661971 
+DEAL:3d-10::0.470142 0.00000 0.0597159 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=1 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-10::0.333333 0.00000 0.333333 0.112500 
+DEAL:3d-10::0.797427 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.101287 0.00000 0.797427 0.0629696 
+DEAL:3d-10::0.101287 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.0597159 0.00000 0.470142 0.0661971 
+DEAL:3d-10::0.470142 0.00000 0.0597159 0.0661971 
+DEAL:3d-10::0.470142 0.00000 0.470142 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=1 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-10::0.333333 0.00000 0.333333 0.112500 
+DEAL:3d-10::0.101287 0.00000 0.797427 0.0629696 
+DEAL:3d-10::0.101287 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.797427 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.470142 0.00000 0.0597159 0.0661971 
+DEAL:3d-10::0.470142 0.00000 0.470142 0.0661971 
+DEAL:3d-10::0.0597159 0.00000 0.470142 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=1 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-10::0.333333 0.00000 0.333333 0.112500 
+DEAL:3d-10::0.101287 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.797427 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.101287 0.00000 0.797427 0.0629696 
+DEAL:3d-10::0.470142 0.00000 0.470142 0.0661971 
+DEAL:3d-10::0.0597159 0.00000 0.470142 0.0661971 
+DEAL:3d-10::0.470142 0.00000 0.0597159 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=1 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-10::0.333333 0.00000 0.333333 0.112500 
+DEAL:3d-10::0.101287 0.00000 0.797427 0.0629696 
+DEAL:3d-10::0.797427 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.101287 0.00000 0.101287 0.0629696 
+DEAL:3d-10::0.470142 0.00000 0.0597159 0.0661971 
+DEAL:3d-10::0.0597159 0.00000 0.470142 0.0661971 
+DEAL:3d-10::0.470142 0.00000 0.470142 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=2 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-10::0.00000 0.333333 0.333333 0.112500 
+DEAL:3d-10::0.00000 0.797427 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.101287 0.797427 0.0629696 
+DEAL:3d-10::0.00000 0.101287 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.0597159 0.470142 0.0661971 
+DEAL:3d-10::0.00000 0.470142 0.0597159 0.0661971 
+DEAL:3d-10::0.00000 0.470142 0.470142 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=2 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-10::0.00000 0.333333 0.333333 0.112500 
+DEAL:3d-10::0.00000 0.101287 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.797427 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.101287 0.797427 0.0629696 
+DEAL:3d-10::0.00000 0.470142 0.470142 0.0661971 
+DEAL:3d-10::0.00000 0.0597159 0.470142 0.0661971 
+DEAL:3d-10::0.00000 0.470142 0.0597159 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=2 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-10::0.00000 0.333333 0.333333 0.112500 
+DEAL:3d-10::0.00000 0.101287 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.101287 0.797427 0.0629696 
+DEAL:3d-10::0.00000 0.797427 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.470142 0.470142 0.0661971 
+DEAL:3d-10::0.00000 0.470142 0.0597159 0.0661971 
+DEAL:3d-10::0.00000 0.0597159 0.470142 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=2 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-10::0.00000 0.333333 0.333333 0.112500 
+DEAL:3d-10::0.00000 0.101287 0.797427 0.0629696 
+DEAL:3d-10::0.00000 0.797427 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.101287 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.470142 0.0597159 0.0661971 
+DEAL:3d-10::0.00000 0.0597159 0.470142 0.0661971 
+DEAL:3d-10::0.00000 0.470142 0.470142 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=2 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-10::0.00000 0.333333 0.333333 0.112500 
+DEAL:3d-10::0.00000 0.797427 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.101287 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.101287 0.797427 0.0629696 
+DEAL:3d-10::0.00000 0.0597159 0.470142 0.0661971 
+DEAL:3d-10::0.00000 0.470142 0.470142 0.0661971 
+DEAL:3d-10::0.00000 0.470142 0.0597159 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=2 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-10::0.00000 0.333333 0.333333 0.112500 
+DEAL:3d-10::0.00000 0.101287 0.797427 0.0629696 
+DEAL:3d-10::0.00000 0.101287 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.797427 0.101287 0.0629696 
+DEAL:3d-10::0.00000 0.470142 0.0597159 0.0661971 
+DEAL:3d-10::0.00000 0.470142 0.470142 0.0661971 
+DEAL:3d-10::0.00000 0.0597159 0.470142 0.0661971 
+DEAL:3d-10::
+DEAL:3d-10::face_no=3 face_orientation=true face_flip=false face_rotation=false:
+DEAL:3d-10::0.333333 0.333333 0.333333 0.194856 
+DEAL:3d-10::0.797427 0.101287 0.101287 0.109067 
+DEAL:3d-10::0.101287 0.101287 0.797427 0.109067 
+DEAL:3d-10::0.101287 0.797427 0.101287 0.109067 
+DEAL:3d-10::0.0597159 0.470142 0.470142 0.114657 
+DEAL:3d-10::0.470142 0.470142 0.0597159 0.114657 
+DEAL:3d-10::0.470142 0.0597159 0.470142 0.114657 
+DEAL:3d-10::
+DEAL:3d-10::face_no=3 face_orientation=true face_flip=true face_rotation=false:
+DEAL:3d-10::0.333333 0.333333 0.333333 0.194856 
+DEAL:3d-10::0.101287 0.797427 0.101287 0.109067 
+DEAL:3d-10::0.797427 0.101287 0.101287 0.109067 
+DEAL:3d-10::0.101287 0.101287 0.797427 0.109067 
+DEAL:3d-10::0.470142 0.0597159 0.470142 0.114657 
+DEAL:3d-10::0.0597159 0.470142 0.470142 0.114657 
+DEAL:3d-10::0.470142 0.470142 0.0597159 0.114657 
+DEAL:3d-10::
+DEAL:3d-10::face_no=3 face_orientation=true face_flip=false face_rotation=true:
+DEAL:3d-10::0.333333 0.333333 0.333333 0.194856 
+DEAL:3d-10::0.101287 0.797427 0.101287 0.109067 
+DEAL:3d-10::0.101287 0.101287 0.797427 0.109067 
+DEAL:3d-10::0.797427 0.101287 0.101287 0.109067 
+DEAL:3d-10::0.470142 0.0597159 0.470142 0.114657 
+DEAL:3d-10::0.470142 0.470142 0.0597159 0.114657 
+DEAL:3d-10::0.0597159 0.470142 0.470142 0.114657 
+DEAL:3d-10::
+DEAL:3d-10::face_no=3 face_orientation=false face_flip=false face_rotation=false:
+DEAL:3d-10::0.333333 0.333333 0.333333 0.194856 
+DEAL:3d-10::0.101287 0.101287 0.797427 0.109067 
+DEAL:3d-10::0.797427 0.101287 0.101287 0.109067 
+DEAL:3d-10::0.101287 0.797427 0.101287 0.109067 
+DEAL:3d-10::0.470142 0.470142 0.0597159 0.114657 
+DEAL:3d-10::0.0597159 0.470142 0.470142 0.114657 
+DEAL:3d-10::0.470142 0.0597159 0.470142 0.114657 
+DEAL:3d-10::
+DEAL:3d-10::face_no=3 face_orientation=false face_flip=true face_rotation=false:
+DEAL:3d-10::0.333333 0.333333 0.333333 0.194856 
+DEAL:3d-10::0.797427 0.101287 0.101287 0.109067 
+DEAL:3d-10::0.101287 0.797427 0.101287 0.109067 
+DEAL:3d-10::0.101287 0.101287 0.797427 0.109067 
+DEAL:3d-10::0.0597159 0.470142 0.470142 0.114657 
+DEAL:3d-10::0.470142 0.0597159 0.470142 0.114657 
+DEAL:3d-10::0.470142 0.470142 0.0597159 0.114657 
+DEAL:3d-10::
+DEAL:3d-10::face_no=3 face_orientation=false face_flip=false face_rotation=true:
+DEAL:3d-10::0.333333 0.333333 0.333333 0.194856 
+DEAL:3d-10::0.101287 0.101287 0.797427 0.109067 
+DEAL:3d-10::0.101287 0.797427 0.101287 0.109067 
+DEAL:3d-10::0.797427 0.101287 0.101287 0.109067 
+DEAL:3d-10::0.470142 0.470142 0.0597159 0.114657 
+DEAL:3d-10::0.470142 0.0597159 0.470142 0.114657 
+DEAL:3d-10::0.0597159 0.470142 0.470142 0.114657 
+DEAL:3d-10::

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.