From 45cae9f551da08f07ffb2cd1dfaf852cbd701150 Mon Sep 17 00:00:00 2001 From: Alexander Grayver Date: Tue, 1 Sep 2020 22:22:23 +0200 Subject: [PATCH] Add python wrappers --- .../include/triangulation_wrapper.h | 9 +- .../source/export_triangulation.cc | 18 ++- .../source/triangulation_wrapper.cc | 137 ++++++++++++------ .../tests/triangulation_wrapper.py | 15 +- 4 files changed, 128 insertions(+), 51 deletions(-) diff --git a/contrib/python-bindings/include/triangulation_wrapper.h b/contrib/python-bindings/include/triangulation_wrapper.h index 7107d54c0c..18269119c8 100644 --- a/contrib/python-bindings/include/triangulation_wrapper.h +++ b/contrib/python-bindings/include/triangulation_wrapper.h @@ -236,8 +236,13 @@ namespace python /*! @copydoc GridGenerator::merge_triangulations */ void - merge_triangulations(TriangulationWrapper &triangulation_1, - TriangulationWrapper &triangulation_2); + merge_triangulations(boost::python::list &triangulations); + + /*! @copydoc GridGenerator::replicate_triangulation + */ + void + replicate_triangulation(TriangulationWrapper &tria_in, + boost::python::list & extents); /*! @copydoc GridGenerator::flatten_triangulation */ diff --git a/contrib/python-bindings/source/export_triangulation.cc b/contrib/python-bindings/source/export_triangulation.cc index 4f32779f20..9c2db2508a 100644 --- a/contrib/python-bindings/source/export_triangulation.cc +++ b/contrib/python-bindings/source/export_triangulation.cc @@ -320,8 +320,8 @@ namespace python const char merge_docstring[] = - "Given two triangulations, create the triangulation that contains \n" - "the cells of both triangulations. \n"; + "Given two or more triangulations, create the triangulation that \n" + "contains the cells of given triangulations. \n"; @@ -354,6 +354,13 @@ namespace python + const char replicate_docstring[] = + "Replicate a given triangulation in multiple coordinate axes. \n" + "This function creates a new Triangulation equal to a dim-dimensional \n" + "array of copies of input. \n"; + + + const char distort_random_docstring[] = "Distort the given triangulation by randomly moving around all the \n" "vertices of the grid. The direction of movement of each vertex is \n" @@ -372,6 +379,7 @@ namespace python "Execute both refinement and coarsening of the Triangulation. \n"; + const char active_cells_docstring[] = "Return the list of active cell accessors of the Triangulation. \n"; @@ -615,7 +623,7 @@ namespace python .def("merge_triangulations", &TriangulationWrapper::merge_triangulations, merge_docstring, - boost::python::args("self", "triangulation_1", "triangulation_2")) + boost::python::args("self", "triangulations")) .def("extrude_triangulation", &TriangulationWrapper::extrude_triangulation, extrude_docstring, @@ -624,6 +632,10 @@ namespace python &TriangulationWrapper::flatten_triangulation, flatten_triangulation_docstring, boost::python::args("self", "tria_out")) + .def("replicate_triangulation", + &TriangulationWrapper::replicate_triangulation, + replicate_docstring, + boost::python::args("self", "tria_in", "extents")) .def("distort_random", &TriangulationWrapper::distort_random, distort_random_overloads( diff --git a/contrib/python-bindings/source/triangulation_wrapper.cc b/contrib/python-bindings/source/triangulation_wrapper.cc index 98a71a1fb7..e5e48cb0db 100644 --- a/contrib/python-bindings/source/triangulation_wrapper.cc +++ b/contrib/python-bindings/source/triangulation_wrapper.cc @@ -514,23 +514,24 @@ namespace python template void - merge_triangulations(TriangulationWrapper &triangulation_1, - TriangulationWrapper &triangulation_2, - void * triangulation) + merge_triangulations(boost::python::list &triangulations, + void * triangulation) { Triangulation *tria = static_cast *>(triangulation); tria->clear(); - Triangulation *tria_1 = - static_cast *>( - triangulation_1.get_triangulation()); - Triangulation *tria_2 = - static_cast *>( - triangulation_2.get_triangulation()); - GridGenerator::merge_triangulations(*tria_1, *tria_2, *tria); - // We need to reassign tria to triangulation because tria was cleared - // inside merge_triangulations. - triangulation = tria; + + std::vector *> tria_ptrs; + size_t n_triangulations = boost::python::len(triangulations); + for (size_t i = 0; i < n_triangulations; ++i) + { + TriangulationWrapper &tria_wrapper = + boost::python::extract(triangulations[i]); + tria_ptrs.push_back(static_cast *>( + tria_wrapper.get_triangulation())); + } + + GridGenerator::merge_triangulations(tria_ptrs, *tria); } @@ -549,6 +550,30 @@ namespace python + template + void + replicate_triangulation(TriangulationWrapper & tria_in, + const boost::python::list &extents, + void * tria_out) + { + Triangulation *replicated_triangulation = + static_cast *>(tria_out); + const Triangulation *triangulation = + static_cast *>( + tria_in.get_triangulation()); + replicated_triangulation->clear(); + + std::vector extents_vector(dim); + for (int d = 0; d < dim; ++d) + extents_vector[d] = boost::python::extract(extents[d]); + + GridGenerator::replicate_triangulation(*triangulation, + extents_vector, + *replicated_triangulation); + } + + + template void distort_random(const double factor, @@ -1411,40 +1436,32 @@ namespace python void TriangulationWrapper::merge_triangulations( - TriangulationWrapper &triangulation_1, - TriangulationWrapper &triangulation_2) + boost::python::list &triangulations) { - AssertThrow( - triangulation_1.get_dim() == triangulation_2.get_dim(), - ExcMessage( - "Triangulation_1 and Triangulation_2 should have the same dimension.")); - AssertThrow( - dim == triangulation_2.get_dim(), - ExcMessage( - "Triangulation and Triangulation_2 should have the same dimension.")); - AssertThrow( - triangulation_1.get_spacedim() == triangulation_2.get_spacedim(), - ExcMessage( - "Triangulation_1 and Triangulation_2 should have the same space dimension.")); - AssertThrow( - spacedim == triangulation_2.get_spacedim(), - ExcMessage( - "Triangulation and Triangulation_2 should have the same space dimension.")); + AssertThrow(boost::python::len(triangulations) >= 2, + ExcMessage( + "You must provide at least two triangulations to merge.")); - if ((triangulation_1.get_dim() == 2) && - (triangulation_1.get_spacedim() == 2)) - internal::merge_triangulations<2, 2>(triangulation_1, - triangulation_2, - triangulation); - else if ((triangulation_1.get_dim() == 2) && - (triangulation_1.get_spacedim() == 3)) - internal::merge_triangulations<2, 3>(triangulation_1, - triangulation_2, - triangulation); + size_t n_triangulations = boost::python::len(triangulations); + for (size_t i = 0; i < n_triangulations; ++i) + { + TriangulationWrapper &tria_wrapper = + boost::python::extract(triangulations[i]); + + AssertThrow(dim == tria_wrapper.get_dim(), + ExcMessage( + "All triangulations must have the same dimension.")); + AssertThrow( + spacedim == tria_wrapper.get_spacedim(), + ExcMessage("All triangulations must have the same space dimension.")); + } + + if ((dim == 2) && (spacedim == 2)) + internal::merge_triangulations<2, 2>(triangulations, triangulation); + else if ((dim == 2) && (spacedim == 3)) + internal::merge_triangulations<2, 3>(triangulations, triangulation); else - internal::merge_triangulations<3, 3>(triangulation_1, - triangulation_2, - triangulation); + internal::merge_triangulations<3, 3>(triangulations, triangulation); } @@ -1495,6 +1512,38 @@ namespace python + void + TriangulationWrapper::replicate_triangulation( + TriangulationWrapper &triangulation_in, + boost::python::list & extents) + { + AssertThrow( + boost::python::len(extents) == dim, + ExcMessage( + "Size of the extents list must be equal to the triangulation dimension.")); + + AssertThrow((triangulation_in.get_dim() == dim) && + (triangulation_in.get_spacedim() == spacedim), + ExcMessage( + "The input Triangulation must be of the same dimension")); + + + if ((dim == 2) && (spacedim == 2)) + internal::replicate_triangulation<2, 2>(triangulation_in, + extents, + triangulation); + else if ((dim == 2) && (spacedim == 3)) + internal::replicate_triangulation<2, 3>(triangulation_in, + extents, + triangulation); + else + internal::replicate_triangulation<3, 3>(triangulation_in, + extents, + triangulation); + } + + + void TriangulationWrapper::distort_random(const double factor, const bool keep_boundary) diff --git a/contrib/python-bindings/tests/triangulation_wrapper.py b/contrib/python-bindings/tests/triangulation_wrapper.py index 4cb19f8e25..09445d2f4a 100644 --- a/contrib/python-bindings/tests/triangulation_wrapper.py +++ b/contrib/python-bindings/tests/triangulation_wrapper.py @@ -356,11 +356,22 @@ class TestTriangulationWrapper(unittest.TestCase): else: triangulation_2.shift([1., 0., 0.]) triangulation = Triangulation(dim[0], dim[1]) - triangulation.merge_triangulations(triangulation_1, - triangulation_2) + triangulation.merge_triangulations([triangulation_1, + triangulation_2]) n_cells = triangulation.n_active_cells() self.assertEqual(n_cells, 2) + def test_replicate(self): + for dim in self.restricted_dim: + triangulation_in = self.build_hyper_cube_triangulation(dim) + triangulation_out = Triangulation(dim[0]) + if (dim[0] == '2D'): + triangulation_out.replicate_triangulation(triangulation_in, [3, 2]); + else: + triangulation_out.replicate_triangulation(triangulation_in, [3, 2, 1]); + n_cells = triangulation_out.n_active_cells() + self.assertEqual(n_cells, 6) + def test_flatten(self): for dim in self.dim: triangulation_1 = self.build_hyper_cube_triangulation(dim) -- 2.39.5