]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add a subdivided_cylinder grid generator and test
authorBruno <blais.bruno@gmail.com>
Thu, 1 Apr 2021 18:44:23 +0000 (14:44 -0400)
committerBruno <blais.bruno@gmail.com>
Thu, 1 Apr 2021 18:44:23 +0000 (14:44 -0400)
include/deal.II/grid/grid_generator.h
source/grid/grid_generator.cc
source/grid/grid_generator_from_name.cc
tests/grid/grid_generator_subdivided_cylinder.cc [new file with mode: 0644]
tests/grid/grid_generator_subdivided_cylinder.output [new file with mode: 0644]

index 8e641c20eacfb6f1351562af8709eef1c938a928..f5b8e90b62411bdb47bfe52591103aaa15df5a21 100644 (file)
@@ -948,6 +948,46 @@ namespace GridGenerator
            const double        radius      = 1.,
            const double        half_length = 1.);
 
+
+  /**
+   * Create a @p dim dimensional cylinder where the $x$-axis serves as
+   * the axis of the cylinder. For the purposes of this function, a
+   * cylinder is defined as a (@p dim - 1) dimensional disk of given
+   * @p radius, extruded along the axis of the cylinder (which is the
+   * first coordinate direction). Consequently, in three dimensions,
+   * the cylinder extends from `x=-half_length` to `x=+half_length`
+   * and its projection into the @p yz-plane is a circle of radius @p
+   * radius. In two dimensions, the cylinder is a rectangle from
+   * `x=-half_length` to `x=+half_length` and from `y=-radius` to
+   * `y=radius`.
+   *
+   * The boundaries are colored according to the following scheme: 0 for the
+   * hull of the cylinder, 1 for the left hand face and 2 for the right hand
+   * face (see
+   * @ref GlossColorization "the glossary entry on colorization").
+   *
+   * The manifold id for the hull of the cylinder is set to zero, and a
+   * CylindricalManifold is attached to it.
+   *
+   * @pre The triangulation passed as argument needs to be empty when calling
+   * this function.
+   *
+   * @param x_subdivisions A positive integer denoting the number
+   * of cells to generate in the x direction. The default cylinder has
+   * x_repetitions=2.
+   *
+   * @param radius The radius of the circle in the yz-plane used to extrude the cylinder.
+   *
+   * @param half_length The half-length of the cylinder in the x direction.
+   */
+  template <int dim>
+  void
+  subdivided_cylinder(Triangulation<dim> &tria,
+                      const unsigned int  x_subdivisions,
+                      const double        radius      = 1.,
+                      const double        half_length = 1.);
+
+
   /**
    * Create a cut cone around the x-axis.  The cone extends from
    * <tt>x=-half_length</tt> to <tt>x=half_length</tt> and its projection into
index c845f2d454974ef59c35aa82e673c3925e4f8b7e..3f2fb6382e6212adfde21cb31ce1c8454dc2b2f1 100644 (file)
@@ -3952,6 +3952,16 @@ namespace GridGenerator
   }
 
 
+  template <>
+  void subdivided_cylinder(Triangulation<1> &,
+                           const unsigned int,
+                           const double,
+                           const double)
+  {
+    Assert(false, ExcNotImplemented());
+  }
+
+
 
   template <>
   void
@@ -4470,6 +4480,15 @@ namespace GridGenerator
       }
   }
 
+  template <>
+  void subdivided_cylinder(Triangulation<2> &,
+                           const unsigned int,
+                           const double,
+                           const double)
+  {
+    Assert(false, ExcNotImplemented());
+  }
+
 
 
   // Implementation for 2D only
@@ -5560,6 +5579,137 @@ namespace GridGenerator
     tria.set_manifold(0, CylindricalManifold<3>());
   }
 
+  // Implementation for 3D only
+  template <>
+  void subdivided_cylinder(Triangulation<3> & tria,
+                           const unsigned int x_subdivisions,
+                           const double       radius,
+                           const double       half_length)
+  {
+    // Copy the base from hyper_ball<3>
+    // and transform it to yz
+    const double d = radius / std::sqrt(2.0);
+    const double a = d / (1 + std::sqrt(2.0));
+
+    // const unsigned int    npts_per_plane = 8;
+    std::vector<Point<3>> vertices;
+    const double          initial_height   = -half_length;
+    const double          height_increment = 2. * half_length / x_subdivisions;
+
+    for (unsigned int rep = 0; rep < (x_subdivisions + 1); ++rep)
+      {
+        const double height = initial_height + height_increment * rep;
+
+        vertices.emplace_back(Point<3>(-d, height, -d));
+        vertices.emplace_back(Point<3>(d, height, -d));
+        vertices.emplace_back(Point<3>(-a, height, -a));
+        vertices.emplace_back(Point<3>(a, height, -a));
+        vertices.emplace_back(Point<3>(-a, height, a));
+        vertices.emplace_back(Point<3>(a, height, a));
+        vertices.emplace_back(Point<3>(-d, height, d));
+        vertices.emplace_back(Point<3>(d, height, d));
+      }
+
+    // Turn cylinder such that y->x
+    for (auto &vertex : vertices)
+      {
+        const double h = vertex(1);
+        vertex(1)      = -vertex(0);
+        vertex(0)      = h;
+      }
+
+    std::vector<std::vector<int>> cell_vertices;
+    cell_vertices.push_back({0, 1, 8, 9, 2, 3, 10, 11});
+    cell_vertices.push_back({0, 2, 8, 10, 6, 4, 14, 12});
+    cell_vertices.push_back({2, 3, 10, 11, 4, 5, 12, 13});
+    cell_vertices.push_back({1, 7, 9, 15, 3, 5, 11, 13});
+    cell_vertices.push_back({6, 4, 14, 12, 7, 5, 15, 13});
+
+    for (unsigned int rep = 1; rep < x_subdivisions; ++rep)
+      {
+        for (unsigned int i = 0; i < 5; ++i)
+          {
+            std::vector<int> new_cell_vertices(8);
+            for (unsigned int j = 0; j < 8; ++j)
+              new_cell_vertices[j] = cell_vertices[i][j] + 8 * rep;
+            cell_vertices.push_back(new_cell_vertices);
+          }
+      }
+
+    unsigned int n_cells = x_subdivisions * 5;
+
+    std::vector<CellData<3>> cells(n_cells, CellData<3>());
+
+    for (unsigned int i = 0; i < n_cells; ++i)
+      {
+        for (unsigned int j = 0; j < 8; ++j)
+          cells[i].vertices[j] = cell_vertices[i][j];
+        cells[i].material_id = 0;
+      }
+
+    tria.create_triangulation(std::vector<Point<3>>(std::begin(vertices),
+                                                    std::end(vertices)),
+                              cells,
+                              SubCellData()); // no boundary information
+
+    // set boundary indicators for the
+    // faces at the ends to 1 and 2,
+    // respectively. note that we also
+    // have to deal with those lines
+    // that are purely in the interior
+    // of the ends. we determine whether
+    // an edge is purely in the
+    // interior if one of its vertices
+    // is at coordinates '+-a' as set
+    // above
+    Triangulation<3>::cell_iterator cell = tria.begin();
+    Triangulation<3>::cell_iterator end  = tria.end();
+
+    tria.set_all_manifold_ids_on_boundary(0);
+
+    for (; cell != end; ++cell)
+      for (unsigned int i : GeometryInfo<3>::face_indices())
+        if (cell->at_boundary(i))
+          {
+            if (cell->face(i)->center()(0) > half_length - 1.e-5)
+              {
+                cell->face(i)->set_boundary_id(2);
+                cell->face(i)->set_manifold_id(numbers::flat_manifold_id);
+
+                for (unsigned int e = 0; e < GeometryInfo<3>::lines_per_face;
+                     ++e)
+                  if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
+                    {
+                      cell->face(i)->line(e)->set_boundary_id(2);
+                      cell->face(i)->line(e)->set_manifold_id(
+                        numbers::flat_manifold_id);
+                    }
+              }
+            else if (cell->face(i)->center()(0) < -half_length + 1.e-5)
+              {
+                cell->face(i)->set_boundary_id(1);
+                cell->face(i)->set_manifold_id(numbers::flat_manifold_id);
+
+                for (unsigned int e = 0; e < GeometryInfo<3>::lines_per_face;
+                     ++e)
+                  if ((std::fabs(cell->face(i)->line(e)->vertex(0)[1]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(0)[2]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(1)[1]) == a) ||
+                      (std::fabs(cell->face(i)->line(e)->vertex(1)[2]) == a))
+                    {
+                      cell->face(i)->line(e)->set_boundary_id(1);
+                      cell->face(i)->line(e)->set_manifold_id(
+                        numbers::flat_manifold_id);
+                    }
+              }
+          }
+    tria.set_manifold(0, CylindricalManifold<3>());
+  }
+
+
 
   template <>
   void quarter_hyper_ball(Triangulation<3> &tria,
index d4823940860f076eae9fca6e076cc313f1ee6052..4fcb174f2d3b03b372dbea840dc3c20ecee77f32 100644 (file)
@@ -142,6 +142,10 @@ namespace GridGenerator
       else if (name == "cylinder")
         parse_and_create<dim, dim, double, double>(cylinder, arguments, tria);
 
+      else if (name == "subdivided_cylinder")
+        parse_and_create<dim, dim, unsigned int, double, double>(
+          subdivided_cylinder, arguments, tria);
+
       else if (name == "truncated_cone")
         parse_and_create<dim, dim, double, double, double>(truncated_cone,
                                                            arguments,
diff --git a/tests/grid/grid_generator_subdivided_cylinder.cc b/tests/grid/grid_generator_subdivided_cylinder.cc
new file mode 100644 (file)
index 0000000..da9999b
--- /dev/null
@@ -0,0 +1,46 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2016 - 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 GridReordering<3>::reorder_cells
+
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_out.h>
+#include <deal.II/grid/tria.h>
+
+#include "../tests.h"
+
+
+
+void
+dim_3(std::ostream &os)
+{
+  const unsigned int d = 3;
+  Triangulation<d>   tr;
+
+  GridGenerator::subdivided_cylinder(tr, 4, 1, 1);
+
+  GridOut gout;
+  gout.write_vtk(tr, os);
+}
+
+int
+main()
+{
+  initlog(true);
+  std::ostream &logfile = deallog.get_file_stream();
+  dim_3(logfile);
+}
diff --git a/tests/grid/grid_generator_subdivided_cylinder.output b/tests/grid/grid_generator_subdivided_cylinder.output
new file mode 100644 (file)
index 0000000..662964b
--- /dev/null
@@ -0,0 +1,164 @@
+
+# vtk DataFile Version 3.0
+Triangulation generated with deal.II
+ASCII
+DATASET UNSTRUCTURED_GRID
+POINTS 40 double
+-1.00000 0.707107 -0.707107
+-1.00000 -0.707107 -0.707107
+-1.00000 0.292893 -0.292893
+-1.00000 -0.292893 -0.292893
+-1.00000 0.292893 0.292893
+-1.00000 -0.292893 0.292893
+-1.00000 0.707107 0.707107
+-1.00000 -0.707107 0.707107
+-0.500000 0.707107 -0.707107
+-0.500000 -0.707107 -0.707107
+-0.500000 0.292893 -0.292893
+-0.500000 -0.292893 -0.292893
+-0.500000 0.292893 0.292893
+-0.500000 -0.292893 0.292893
+-0.500000 0.707107 0.707107
+-0.500000 -0.707107 0.707107
+0.00000 0.707107 -0.707107
+0.00000 -0.707107 -0.707107
+0.00000 0.292893 -0.292893
+0.00000 -0.292893 -0.292893
+0.00000 0.292893 0.292893
+0.00000 -0.292893 0.292893
+0.00000 0.707107 0.707107
+0.00000 -0.707107 0.707107
+0.500000 0.707107 -0.707107
+0.500000 -0.707107 -0.707107
+0.500000 0.292893 -0.292893
+0.500000 -0.292893 -0.292893
+0.500000 0.292893 0.292893
+0.500000 -0.292893 0.292893
+0.500000 0.707107 0.707107
+0.500000 -0.707107 0.707107
+1.00000 0.707107 -0.707107
+1.00000 -0.707107 -0.707107
+1.00000 0.292893 -0.292893
+1.00000 -0.292893 -0.292893
+1.00000 0.292893 0.292893
+1.00000 -0.292893 0.292893
+1.00000 0.707107 0.707107
+1.00000 -0.707107 0.707107
+
+CELLS 98 466
+8 0 1 9 8 2 3 11 10
+8 0 2 10 8 6 4 12 14
+8 2 3 11 10 4 5 13 12
+8 1 7 15 9 3 5 13 11
+8 6 4 12 14 7 5 13 15
+8 8 9 17 16 10 11 19 18
+8 8 10 18 16 14 12 20 22
+8 10 11 19 18 12 13 21 20
+8 9 15 23 17 11 13 21 19
+8 14 12 20 22 15 13 21 23
+8 16 17 25 24 18 19 27 26
+8 16 18 26 24 22 20 28 30
+8 18 19 27 26 20 21 29 28
+8 17 23 31 25 19 21 29 27
+8 22 20 28 30 23 21 29 31
+8 24 25 33 32 26 27 35 34
+8 24 26 34 32 30 28 36 38
+8 26 27 35 34 28 29 37 36
+8 25 31 39 33 27 29 37 35
+8 30 28 36 38 31 29 37 39
+4 0 2 3 1
+4 0 6 4 2
+4 0 8 14 6
+4 0 1 9 8
+4 1 3 5 7
+4 1 7 15 9
+4 2 4 5 3
+4 6 7 5 4
+4 6 14 15 7
+4 8 16 22 14
+4 8 9 17 16
+4 9 15 23 17
+4 14 22 23 15
+4 16 24 30 22
+4 16 17 25 24
+4 17 23 31 25
+4 22 30 31 23
+4 24 32 38 30
+4 24 25 33 32
+4 25 31 39 33
+4 30 38 39 31
+4 32 34 35 33
+4 32 38 36 34
+4 33 35 37 39
+4 34 36 37 35
+4 38 39 37 36
+2 0 1
+2 2 3
+2 0 2
+2 1 3
+2 6 4
+2 0 6
+2 2 4
+2 0 8
+2 8 14
+2 6 14
+2 1 9
+2 8 9
+2 1 7
+2 3 5
+2 7 5
+2 7 15
+2 9 15
+2 4 5
+2 6 7
+2 14 15
+2 8 16
+2 16 22
+2 14 22
+2 9 17
+2 16 17
+2 15 23
+2 17 23
+2 22 23
+2 16 24
+2 24 30
+2 22 30
+2 17 25
+2 24 25
+2 23 31
+2 25 31
+2 30 31
+2 32 34
+2 24 32
+2 32 38
+2 30 38
+2 25 33
+2 32 33
+2 33 35
+2 31 39
+2 33 39
+2 34 36
+2 34 35
+2 35 37
+2 36 37
+2 38 39
+2 38 36
+2 39 37
+
+CELL_TYPES 98
+12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 
+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 
+3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 
+
+CELL_DATA 98
+SCALARS MaterialID int 1
+LOOKUP_TABLE default
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 
+0 1 1 1 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 2 0 0 2 2 2 2 0 2 2 
+
+SCALARS ManifoldID int 1
+LOOKUP_TABLE default
+-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
+-1 -1 0 0 -1 0 -1 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 -1 -1 -1 
+0 -1 -1 -1 -1 0 -1 0 0 0 0 0 0 -1 -1 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 -1 0 0 -1 -1 -1 -1 0 -1 -1 

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.