Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add get/set_mesh_smoothing to python bindings. #14549

Merged
merged 1 commit into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
60 changes: 55 additions & 5 deletions contrib/python-bindings/include/triangulation_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,56 @@ namespace python
public:
typedef std::vector<CellAccessorWrapper>::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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
55 changes: 51 additions & 4 deletions contrib/python-bindings/source/export_triangulation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -491,9 +501,16 @@ namespace python
{
boost::python::class_<TriangulationWrapper>(
"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")))
boost::python::init<const std::string &,
boost::python::optional<const int, const bool>>(
boost::python::args("dim",
"mesh_smoothing",
"check_for_distorted_cells")))
.def(boost::python::init<const std::string &,
const std::string &,
boost::python::optional<const int, const bool>>(
boost::python::args(
"dim", "spacedim", "mesh_smoothing", "check_for_distorted_cells")))
.def("n_active_cells",
&TriangulationWrapper::n_active_cells,
n_active_cells_docstring,
Expand Down Expand Up @@ -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_<TriangulationWrapper::MeshSmoothing>("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

Expand Down
87 changes: 77 additions & 10 deletions contrib/python-bindings/source/triangulation_wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}


Expand Down Expand Up @@ -1977,9 +1983,64 @@ namespace python



int
TriangulationWrapper::get_mesh_smoothing()
{
if ((dim == 2) && (spacedim == 2))
{
Triangulation<2, 2> *tria =
static_cast<Triangulation<2, 2> *>(triangulation);
return (int)tria->get_mesh_smoothing();
}
else if ((dim == 2) && (spacedim == 3))
{
Triangulation<2, 3> *tria =
static_cast<Triangulation<2, 3> *>(triangulation);
return (int)tria->get_mesh_smoothing();
}
else
{
Triangulation<3, 3> *tria =
static_cast<Triangulation<3, 3> *>(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<2, 2> *>(triangulation);
tria->set_mesh_smoothing(
(Triangulation<2, 2>::MeshSmoothing)mesh_smoothing);
}
else if ((dim == 2) && (spacedim == 3))
{
Triangulation<2, 3> *tria =
static_cast<Triangulation<2, 3> *>(triangulation);
tria->set_mesh_smoothing(
(Triangulation<2, 3>::MeshSmoothing)mesh_smoothing);
}
else
{
Triangulation<3, 3> *tria =
static_cast<Triangulation<3, 3> *>(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))
{
Expand All @@ -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,
Expand All @@ -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."));
Expand Down
19 changes: 18 additions & 1 deletion contrib/python-bindings/tests/triangulation_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def test_generate_cheese(self):
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])
Expand Down Expand Up @@ -464,5 +464,22 @@ def test_save_load(self):
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()