From c1f8ca3d2f71149f435754aa2b7cf33c8320acec Mon Sep 17 00:00:00 2001 From: Ce Qin Date: Thu, 8 Dec 2022 23:35:00 +0800 Subject: [PATCH] Add get/set_mesh_smoothing to python bindings. --- .../include/triangulation_wrapper.h | 60 +++++++++++-- .../source/export_triangulation.cc | 55 +++++++++++- .../source/triangulation_wrapper.cc | 87 ++++++++++++++++--- .../tests/triangulation_wrapper.py | 19 +++- 4 files changed, 201 insertions(+), 20 deletions(-) diff --git a/contrib/python-bindings/include/triangulation_wrapper.h b/contrib/python-bindings/include/triangulation_wrapper.h index 5a2c2aecb4..5c41a14e43 100644 --- a/contrib/python-bindings/include/triangulation_wrapper.h +++ b/contrib/python-bindings/include/triangulation_wrapper.h @@ -39,19 +39,56 @@ namespace python public: typedef std::vector::iterator iterator; + /** + * Declare some symbolic names for mesh smoothing. These values are copied + * from the Triangulation class, please find the documentation for their + * meanings. + */ + enum MeshSmoothing + { + none = 0x0, + limit_level_difference_at_vertices = 0x1, + eliminate_unrefined_islands = 0x2, + patch_level_1 = 0x4, + coarsest_level_1 = 0x8, + allow_anisotropic_smoothing = 0x10, + eliminate_refined_inner_islands = 0x100, + eliminate_refined_boundary_islands = 0x200, + do_not_produce_unrefined_islands = 0x400, + smoothing_on_refinement = + (limit_level_difference_at_vertices | eliminate_unrefined_islands), + smoothing_on_coarsening = + (eliminate_refined_inner_islands | eliminate_refined_boundary_islands | + do_not_produce_unrefined_islands), + maximum_smoothing = 0xffff ^ allow_anisotropic_smoothing + }; + /** * Constructor. Takes a string @p dim with one of the following values - * "2D", "2d", "3D", or "3d". + * "2D", "2d", "3D", or "3d". The optional @p mesh_smoothing determines + * the level of smoothness of the mesh size function that should be enforced + * upon mesh refinement. The optional @p check_for_distorted_cells + * determines whether the triangulation should check whether any of the + * cells are distorted. */ - TriangulationWrapper(const std::string &dim); + TriangulationWrapper(const std::string &dim, + const int mesh_smoothing = none, + const bool check_for_distorted_cells = false); /** * Constructor. Takes a string @p dim with one of the following values * "2D", "2d", "3D", or "3d" and a string @p spacedim with one of the * following values "2D", "2d", "3D", or "3d". The dimension of @p spacedim - * must be larger than the dimension of @p dim + * must be larger than the dimension of @p dim. The optional @p mesh_smoothing + * determines the level of smoothness of the mesh size function that should + * be enforced upon mesh refinement. The optional @p check_for_distorted_cells + * determines whether the triangulation should check whether any of the + * cells are distorted. */ - TriangulationWrapper(const std::string &dim, const std::string &spacedim); + TriangulationWrapper(const std::string &dim, + const std::string &spacedim, + const int mesh_smoothing = none, + const bool check_for_distorted_cells = false); /** * Destructor. @@ -300,6 +337,16 @@ namespace python void reset_manifold(const int number); + /*! @copydoc Triangulation::get_mesh_smoothing + */ + int + get_mesh_smoothing(); + + /*! @copydoc Triangulation::set_mesh_smoothing + */ + void + set_mesh_smoothing(const int mesh_smoothing); + /*! @copydoc Triangulation::refine_global */ void @@ -390,7 +437,10 @@ namespace python * Helper function for the constructors. */ void - setup(const std::string &dimension, const std::string &spacedimension); + setup(const std::string &dimension, + const std::string &spacedimension, + const int mesh_smoothing, + const bool check_for_distorted_cells); /** * Dimension of the underlying Triangulation object. diff --git a/contrib/python-bindings/source/export_triangulation.cc b/contrib/python-bindings/source/export_triangulation.cc index 043da212d6..a3d7cd2d30 100644 --- a/contrib/python-bindings/source/export_triangulation.cc +++ b/contrib/python-bindings/source/export_triangulation.cc @@ -447,6 +447,16 @@ namespace python + const char get_mesh_smoothing_docstring[] = + "Return the mesh smoothing requirements that are obeyed. \n"; + + + + const char set_mesh_smoothing_docstring[] = + "Set the mesh smoothing to mesh_smoothing. \n"; + + + const char transform_docstring[] = "Transform the vertices of the given triangulation by applying the \n" "function object provided as first argument to all its vertices. \n"; @@ -491,9 +501,16 @@ namespace python { boost::python::class_( "Triangulation", - boost::python::init(boost::python::args("dim"))) - .def(boost::python::init( - boost::python::args("dim", "spacedim"))) + boost::python::init>( + boost::python::args("dim", + "mesh_smoothing", + "check_for_distorted_cells"))) + .def(boost::python::init>( + boost::python::args( + "dim", "spacedim", "mesh_smoothing", "check_for_distorted_cells"))) .def("n_active_cells", &TriangulationWrapper::n_active_cells, n_active_cells_docstring, @@ -728,7 +745,37 @@ namespace python .def("reset_manifold", &TriangulationWrapper::reset_manifold, reset_manifold_docstring, - boost::python::args("self", "number")); + boost::python::args("self", "number")) + .def("get_mesh_smoothing", + &TriangulationWrapper::get_mesh_smoothing, + get_mesh_smoothing_docstring, + boost::python::args("self")) + .def("set_mesh_smoothing", + &TriangulationWrapper::set_mesh_smoothing, + set_mesh_smoothing_docstring, + boost::python::args("self", "mesh_smoothing")); + + boost::python::enum_("MeshSmoothing") + .value("none", TriangulationWrapper::none) + .value("limit_level_difference_at_vertices", + TriangulationWrapper::limit_level_difference_at_vertices) + .value("eliminate_unrefined_islands", + TriangulationWrapper::eliminate_unrefined_islands) + .value("patch_level_1", TriangulationWrapper::patch_level_1) + .value("coarsest_level_1", TriangulationWrapper::coarsest_level_1) + .value("allow_anisotropic_smoothing", + TriangulationWrapper::allow_anisotropic_smoothing) + .value("eliminate_refined_inner_islands", + TriangulationWrapper::eliminate_refined_inner_islands) + .value("eliminate_refined_boundary_islands", + TriangulationWrapper::eliminate_refined_boundary_islands) + .value("do_not_produce_unrefined_islands", + TriangulationWrapper::do_not_produce_unrefined_islands) + .value("smoothing_on_refinement", + TriangulationWrapper::smoothing_on_refinement) + .value("smoothing_on_coarsening", + TriangulationWrapper::smoothing_on_coarsening) + .value("maximum_smoothing", TriangulationWrapper::maximum_smoothing); } } // namespace python diff --git a/contrib/python-bindings/source/triangulation_wrapper.cc b/contrib/python-bindings/source/triangulation_wrapper.cc index 59ea1e1711..ffa1fe52ce 100644 --- a/contrib/python-bindings/source/triangulation_wrapper.cc +++ b/contrib/python-bindings/source/triangulation_wrapper.cc @@ -852,22 +852,28 @@ namespace python - TriangulationWrapper::TriangulationWrapper(const std::string &dimension) + TriangulationWrapper::TriangulationWrapper( + const std::string &dimension, + const int mesh_smoothing, + const bool check_for_distorted_cells) { if ((dimension.compare("2D") == 0) || (dimension.compare("2d") == 0)) - setup("2D", "2D"); + setup("2D", "2D", mesh_smoothing, check_for_distorted_cells); else if ((dimension.compare("3D") == 0) || (dimension.compare("3d") == 0)) - setup("3D", "3D"); + setup("3D", "3D", mesh_smoothing, check_for_distorted_cells); else AssertThrow(false, ExcMessage("Dimension needs to be 2D or 3D")); } - TriangulationWrapper::TriangulationWrapper(const std::string &dimension, - const std::string &spacedimension) + TriangulationWrapper::TriangulationWrapper( + const std::string &dimension, + const std::string &spacedimension, + const int mesh_smoothing, + const bool check_for_distorted_cells) { - setup(dimension, spacedimension); + setup(dimension, spacedimension, mesh_smoothing, check_for_distorted_cells); } @@ -1977,9 +1983,64 @@ namespace python + int + TriangulationWrapper::get_mesh_smoothing() + { + if ((dim == 2) && (spacedim == 2)) + { + Triangulation<2, 2> *tria = + static_cast *>(triangulation); + return (int)tria->get_mesh_smoothing(); + } + else if ((dim == 2) && (spacedim == 3)) + { + Triangulation<2, 3> *tria = + static_cast *>(triangulation); + return (int)tria->get_mesh_smoothing(); + } + else + { + Triangulation<3, 3> *tria = + static_cast *>(triangulation); + return (int)tria->get_mesh_smoothing(); + } + } + + + + void + TriangulationWrapper::set_mesh_smoothing(const int mesh_smoothing) + { + if ((dim == 2) && (spacedim == 2)) + { + Triangulation<2, 2> *tria = + static_cast *>(triangulation); + tria->set_mesh_smoothing( + (Triangulation<2, 2>::MeshSmoothing)mesh_smoothing); + } + else if ((dim == 2) && (spacedim == 3)) + { + Triangulation<2, 3> *tria = + static_cast *>(triangulation); + tria->set_mesh_smoothing( + (Triangulation<2, 3>::MeshSmoothing)mesh_smoothing); + } + else + { + Triangulation<3, 3> *tria = + static_cast *>(triangulation); + tria->set_mesh_smoothing( + (Triangulation<3, 3>::MeshSmoothing)mesh_smoothing); + } + } + + + void TriangulationWrapper::setup(const std::string &dimension, - const std::string &spacedimension) + const std::string &spacedimension, + const int mesh_smoothing, + const bool check_for_distorted_cells) { if ((dimension.compare("2D") == 0) || (dimension.compare("2d") == 0)) { @@ -1989,13 +2050,17 @@ namespace python (spacedimension.compare("2d") == 0)) { spacedim = 2; - triangulation = new Triangulation<2, 2>(); + triangulation = new Triangulation<2, 2>( + (Triangulation<2, 2>::MeshSmoothing)mesh_smoothing, + check_for_distorted_cells); } else if ((spacedimension.compare("3D") == 0) || (spacedimension.compare("3d") == 0)) { spacedim = 3; - triangulation = new Triangulation<2, 3>(); + triangulation = new Triangulation<2, 3>( + (Triangulation<2, 3>::MeshSmoothing)mesh_smoothing, + check_for_distorted_cells); } else AssertThrow(false, @@ -2008,7 +2073,9 @@ namespace python AssertThrow(false, ExcMessage("Spacedimension needs to be 3D.")); dim = 3; spacedim = 3; - triangulation = new Triangulation<3, 3>(); + triangulation = new Triangulation<3, 3>( + (Triangulation<3, 3>::MeshSmoothing)mesh_smoothing, + check_for_distorted_cells); } else AssertThrow(false, ExcMessage("Dimension needs to be 2D or 3D.")); diff --git a/contrib/python-bindings/tests/triangulation_wrapper.py b/contrib/python-bindings/tests/triangulation_wrapper.py index 17073ef7d0..e1cedcee41 100644 --- a/contrib/python-bindings/tests/triangulation_wrapper.py +++ b/contrib/python-bindings/tests/triangulation_wrapper.py @@ -177,7 +177,7 @@ class TestTriangulationWrapper(unittest.TestCase): triangulation.generate_cheese(holes) n_cells = triangulation.n_active_cells() self.assertEqual(n_cells, 175) - + def test_generate_general_cell(self): for dim in self.restricted_dim: triangulation = Triangulation(dim[0], dim[1]) @@ -464,5 +464,22 @@ class TestTriangulationWrapper(unittest.TestCase): self.assertEqual(n_cells, 8) + def test_mesh_smoothing(self): + tria = Triangulation('2D') + self.assertEqual(tria.get_mesh_smoothing(), MeshSmoothing.none) + tria.set_mesh_smoothing(MeshSmoothing.maximum_smoothing) + self.assertEqual(tria.get_mesh_smoothing(), MeshSmoothing.maximum_smoothing) + + tria = Triangulation('2D', MeshSmoothing.limit_level_difference_at_vertices) + self.assertEqual(tria.get_mesh_smoothing(), MeshSmoothing.limit_level_difference_at_vertices) + + tria = Triangulation('2D', '3D', MeshSmoothing.none, False) + tria.set_mesh_smoothing(MeshSmoothing.limit_level_difference_at_vertices) + self.assertEqual(tria.get_mesh_smoothing(), MeshSmoothing.limit_level_difference_at_vertices) + + tria = Triangulation('3D', MeshSmoothing.limit_level_difference_at_vertices | MeshSmoothing.do_not_produce_unrefined_islands) + self.assertEqual(tria.get_mesh_smoothing(), MeshSmoothing.limit_level_difference_at_vertices | MeshSmoothing.do_not_produce_unrefined_islands) + + if __name__ == '__main__': unittest.main() -- 2.39.5