]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add more python binds
authorAlexander Grayver <agrayver@erdw.ethz.ch>
Tue, 11 Feb 2020 15:41:17 +0000 (16:41 +0100)
committerAlexander Grayver <agrayver@erdw.ethz.ch>
Wed, 12 Feb 2020 09:05:37 +0000 (10:05 +0100)
contrib/python-bindings/include/triangulation_wrapper.h
contrib/python-bindings/source/export_triangulation.cc
contrib/python-bindings/source/triangulation_wrapper.cc
contrib/python-bindings/tests/triangulation_wrapper.py
doc/news/changes/minor/20200211Grayver [new file with mode: 0644]

index ab9da0868eb19eb0c72c971ab338ce6c8583445a..3639186059f5f8491dbf818ccec2d81e0cfeeef6 100644 (file)
@@ -58,6 +58,14 @@ namespace python
      */
     ~TriangulationWrapper();
 
+    /**
+     * Create a triangulation from a list of vertices and a list of indices,
+     * each of the latter being a list of 1<<dim vertex indices.
+     */
+    void
+    create_triangulation(const boost::python::list &vertices,
+                         const boost::python::list &cells_vertices);
+
     /**
      * Return the number of active cells.
      */
@@ -137,6 +145,16 @@ namespace python
       boost::python::list &material_id,
       const bool           colorize = false);
 
+    /*! @copydoc GridGenerator::hyper_cube_with_cylindrical_hole
+     */
+    void
+    generate_hyper_cube_with_cylindrical_hole(
+      const double       inner_radius = .25,
+      const double       outer_radius = .5,
+      const double       L            = .5,
+      const unsigned int repetitions  = 1,
+      const bool         colorize     = false);
+
     /**
      * Rectangular domain with rectangular pattern of holes. The domain itself
      * is rectangular, very much as if it had been generated by
@@ -289,6 +307,13 @@ namespace python
     void
     shift(boost::python::list &shift_list);
 
+    /**
+     * Scale the entire triangulation by the given factor. To preserve
+     * the orientation of the triangulation, the factor must be positive.
+     */
+    void
+    scale(const double scaling_factor);
+
     /**
      * Given two triangulations, create the triangulation that contains the
      * cells of both triangulations.
index 629de32fcb3f7b3b8f24052475f4586242028ee8..b5a601215bb9310c11583346f4f13b1c372b7eaf 100644 (file)
@@ -77,6 +77,11 @@ namespace python
                                          generate_enclosed_hyper_cube,
                                          0,
                                          4)
+  BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(
+    generate_hyper_cube_with_cylindrical_hole_overloads,
+    generate_hyper_cube_with_cylindrical_hole,
+    0,
+    5)
   BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_hyper_ball_overloads,
                                          generate_hyper_ball,
                                          1,
@@ -122,6 +127,12 @@ namespace python
 
 
 
+  const char create_triangulation_docstring[] =
+    "Given a list of points and how vertices connect to cells, create a     \n"
+    "mesh.                                                                  \n";
+
+
+
   const char generate_hyper_cube_docstring[] =
     "Generate a hyper_cube (square in 2D and cube in 3D)                    \n"
     "with exactly one cell.                                                 \n";
@@ -291,11 +302,23 @@ namespace python
 
 
 
+  const char generate_hyper_cube_with_cylindrical_hole_docstring[] =
+    "This function produces a square in the xy-plane with a cylindrical     \n"
+    "hole in the middle. In 3d, this geometry is extruded in z direction    \n"
+    "to the interval [0,L].                                                 \n";
+
+
+
   const char shift_docstring[] =
     "Shift every vertex of the Triangulation by the given shift vector.     \n";
 
 
 
+  const char scale_docstring[] =
+    "Scale triangulation by a given scaling factor.                         \n";
+
+
+
   const char merge_docstring[] =
     "Given two triangulations, create the triangulation that contains       \n"
     "the cells of both triangulations.                                      \n";
@@ -438,8 +461,10 @@ namespace python
   export_triangulation()
   {
     boost::python::class_<TriangulationWrapper>(
-      "Triangulation", boost::python::init<const std::string &>())
-      .def(boost::python::init<const std::string &, const std::string &>())
+      "Triangulation",
+      boost::python::init<const std::string &>(boost::python::args("dim")))
+      .def(boost::python::init<const std::string &, const std::string &>(
+        boost::python::args("dim", "spacedim")))
       .def("n_active_cells",
            &TriangulationWrapper::n_active_cells,
            n_active_cells_docstring,
@@ -464,6 +489,10 @@ namespace python
            &TriangulationWrapper::maximal_cell_diameter,
            maximal_cell_diameter_docstring,
            boost::python::args("self"))
+      .def("create_triangulation",
+           &TriangulationWrapper::create_triangulation,
+           create_triangulation_docstring,
+           boost::python::args("self", "vertices", "cells_vertices"))
       .def("generate_hyper_cube",
            &TriangulationWrapper::generate_hyper_cube,
            generate_hyper_cube_overloads(
@@ -499,6 +528,16 @@ namespace python
              boost::python::args(
                "self", "spacing", "p", "material_id", "colorize"),
              generate_subdivided_material_hyper_rectangle_docstring))
+      .def("generate_hyper_cube_with_cylindrical_hole",
+           &TriangulationWrapper::generate_hyper_cube_with_cylindrical_hole,
+           generate_hyper_cube_with_cylindrical_hole_overloads(
+             boost::python::args("self",
+                                 "inner_radius",
+                                 "outer_radius",
+                                 "L",
+                                 "repetitions",
+                                 "colorize"),
+             generate_hyper_cube_with_cylindrical_hole_docstring))
       .def("generate_cheese",
            &TriangulationWrapper::generate_cheese,
            generate_cheese_docstring,
@@ -569,6 +608,10 @@ namespace python
            &TriangulationWrapper::shift,
            shift_docstring,
            boost::python::args("self", "shift"))
+      .def("scale",
+           &TriangulationWrapper::scale,
+           scale_docstring,
+           boost::python::args("self", "scaling_factor"))
       .def("merge_triangulations",
            &TriangulationWrapper::merge_triangulations,
            merge_docstring,
index a33173029a46723c7893de1ed9d36f2fcf6fb3f6..e07bda593b5dae1ca2380f5078879f7bd11872fc 100644 (file)
@@ -35,6 +35,43 @@ namespace python
 {
   namespace internal
   {
+    template <int dim, int spacedim>
+    void
+    create_triangulation(const boost::python::list &vertices_list,
+                         const boost::python::list &cells_vertices,
+                         void *                     triangulation)
+    {
+      Triangulation<dim, spacedim> *tria =
+        static_cast<Triangulation<dim, spacedim> *>(triangulation);
+      tria->clear();
+
+      const size_t n_vertices = boost::python::len(vertices_list);
+      std::vector<Point<spacedim>> vertices(n_vertices);
+      for (size_t i = 0; i < n_vertices; ++i)
+        {
+          boost::python::list vertex =
+            boost::python::extract<boost::python::list>(vertices_list[i]);
+          for (int d = 0; d < spacedim; ++d)
+            vertices[i][d] = boost::python::extract<double>(vertex[d]);
+        }
+
+      const size_t               n_cells = boost::python::len(cells_vertices);
+      std::vector<CellData<dim>> cell_data(n_cells);
+      for (size_t i = 0; i < n_cells; ++i)
+        {
+          boost::python::list vertex_indices =
+            boost::python::extract<boost::python::list>(cells_vertices[i]);
+
+          for (unsigned int v = 0; v < GeometryInfo<dim>::vertices_per_cell;
+               ++v)
+            cell_data[i].vertices[v] =
+              boost::python::extract<unsigned int>(vertex_indices[v]);
+        }
+
+      tria->create_triangulation(vertices, cell_data, SubCellData());
+    }
+
+
     template <int dim, int spacedim>
     void
     generate_hyper_cube(const double left,
@@ -110,6 +147,23 @@ namespace python
     }
 
 
+    template <int dim>
+    void
+    generate_hyper_cube_with_cylindrical_hole(const double       inner_radius,
+                                              const double       outer_radius,
+                                              const double       L,
+                                              const unsigned int repetitions,
+                                              const bool         colorize,
+                                              void *             triangulation)
+    {
+      Triangulation<dim> *tria =
+        static_cast<Triangulation<dim> *>(triangulation);
+      tria->clear();
+      GridGenerator::hyper_cube_with_cylindrical_hole(
+        *tria, inner_radius, outer_radius, L, repetitions, colorize);
+    }
+
+
 
     template <int dim, int spacedim>
     void
@@ -431,6 +485,17 @@ namespace python
 
 
 
+    template <int dim, int spacedim>
+    void
+    scale(const double scaling_factor, void *triangulation)
+    {
+      Triangulation<dim, spacedim> *tria =
+        static_cast<Triangulation<dim, spacedim> *>(triangulation);
+      GridTools::scale(scaling_factor, *tria);
+    }
+
+
+
     template <int dim, int spacedim>
     void
     shift(boost::python::list &shift_list, void *triangulation)
@@ -793,6 +858,27 @@ namespace python
 
 
 
+  void
+  TriangulationWrapper::create_triangulation(
+    const boost::python::list &vertices,
+    const boost::python::list &cells_vertices)
+  {
+    if ((dim == 2) && (spacedim == 2))
+      internal::create_triangulation<2, 2>(vertices,
+                                           cells_vertices,
+                                           triangulation);
+    else if ((dim == 2) && (spacedim == 3))
+      internal::create_triangulation<2, 3>(vertices,
+                                           cells_vertices,
+                                           triangulation);
+    else
+      internal::create_triangulation<3, 3>(vertices,
+                                           cells_vertices,
+                                           triangulation);
+  }
+
+
+
   void
   TriangulationWrapper::generate_hyper_cube(const double left,
                                             const double right,
@@ -1270,6 +1356,29 @@ namespace python
 
 
 
+  void
+  TriangulationWrapper::generate_hyper_cube_with_cylindrical_hole(
+    const double       inner_radius,
+    const double       outer_radius,
+    const double       L,
+    const unsigned int repetitions,
+    const bool         colorize)
+  {
+    AssertThrow(
+      dim == spacedim,
+      ExcMessage(
+        "This function is only implemented for dim equal to spacedim."));
+
+    if (dim == 2)
+      internal::generate_hyper_cube_with_cylindrical_hole<2>(
+        inner_radius, outer_radius, L, repetitions, colorize, triangulation);
+    else
+      internal::generate_hyper_cube_with_cylindrical_hole<3>(
+        inner_radius, outer_radius, L, repetitions, colorize, triangulation);
+  }
+
+
+
   void
   TriangulationWrapper::shift(boost::python::list &shift_list)
   {
@@ -1286,6 +1395,19 @@ namespace python
 
 
 
+  void
+  TriangulationWrapper::scale(const double scaling_factor)
+  {
+    if ((dim == 2) && (spacedim == 2))
+      internal::scale<2, 2>(scaling_factor, triangulation);
+    else if ((dim == 2) && (spacedim == 3))
+      internal::scale<2, 3>(scaling_factor, triangulation);
+    else
+      internal::scale<3, 3>(scaling_factor, triangulation);
+  }
+
+
+
   void
   TriangulationWrapper::merge_triangulations(
     TriangulationWrapper &triangulation_1,
index 890f9050661d06bea6e689d9c79fc02a697eaf29..bd13b682a6788b43184cd9154658f873754db03c 100644 (file)
@@ -62,6 +62,22 @@ class TestTriangulationWrapper(unittest.TestCase):
             n_cells = triangulation.n_active_cells()
             self.assertEqual(n_cells, len(vertices))
 
+    def test_create_triangulation(self):
+        for dim in self.dim:
+            triangulation = Triangulation(dim[0])
+            if (dim[0] == '2D'):
+                vertices = [[0., 0.], [1., 0.], [0., 1.], [1., 1.]]
+                cell_vertices = [[0, 1, 2, 3]]
+            else:
+                vertices = [[0., 0., 0.], [1., 0., 0.],\
+                            [0., 1., 0.], [1., 1., 0.],\
+                            [0., 0., 1.], [1., 0., 1.],\
+                            [0., 1., 1.], [1., 1., 1.]]
+                cell_vertices = [[0, 1, 2, 3, 4, 5, 6, 7]]
+            triangulation.create_triangulation(vertices, cell_vertices)
+            n_cells = triangulation.n_active_cells()
+            self.assertEqual(n_cells, len(cell_vertices))
+
     def test_subdivided_hyper_cube(self):
         for dim in self.dim:
             triangulation = Triangulation(dim[0], dim[1])
@@ -140,7 +156,15 @@ class TestTriangulationWrapper(unittest.TestCase):
                 n_cells = triangulation.n_active_cells()
                 self.assertEqual(n_cells, 17)
 
-    def test_generate_chees(self):
+    def test_hyper_cube_with_cylindrical_hole(self):
+        for dim in self.restricted_dim:
+            triangulation = Triangulation(dim[0])
+            triangulation.generate_hyper_cube_with_cylindrical_hole(inner_radius = .25,
+                               outer_radius = .5, L = .5, repetitions = 1, colorize = False)
+            n_cells = triangulation.n_active_cells()
+            self.assertEqual(n_cells, 8)
+
+    def test_generate_cheese(self):
         for dim in self.dim:
             triangulation = Triangulation(dim[0], dim[1])
             if (dim[0] == '2D'):
diff --git a/doc/news/changes/minor/20200211Grayver b/doc/news/changes/minor/20200211Grayver
new file mode 100644 (file)
index 0000000..f901479
--- /dev/null
@@ -0,0 +1,4 @@
+Add: python binds for Triangulation::create_triangulation, GridTools::scale
+and GridGenerator::hyper_cube_with_cylindrical_hole.
+<br>
+(Alexander Grayver, 2020/02/11)

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.