From 87bb132536b43f13fd18a6a6fc8ef4eed3b90f8a Mon Sep 17 00:00:00 2001 From: Bruno Turcksin Date: Thu, 16 Jun 2016 09:57:59 -0400 Subject: [PATCH] Add tests and fix a few bugs. --- include/deal.II/python/point_wrapper.h | 37 +++++- source/python/export_triangulation.cc | 2 +- source/python/point_wrapper.cc | 77 ++++++++++--- source/python/triangulation_wrapper.cc | 27 ++++- tests/python/point_wrapper.py | 45 ++++++++ tests/python/triangulation_wrapper.py | 151 +++++++++++++++++++++++++ 6 files changed, 316 insertions(+), 23 deletions(-) create mode 100644 tests/python/point_wrapper.py create mode 100644 tests/python/triangulation_wrapper.py diff --git a/include/deal.II/python/point_wrapper.h b/include/deal.II/python/point_wrapper.h index bce81d97b7..2206515a20 100644 --- a/include/deal.II/python/point_wrapper.h +++ b/include/deal.II/python/point_wrapper.h @@ -34,10 +34,21 @@ namespace PyDealII PointWrapper(boost::python::list list); /** - * Destructpr. + * Copy constructor. + */ + PointWrapper(const PointWrapper &other); + + /** + * Destructor. */ ~PointWrapper(); + /** + * Assignment operator. The dimension of the point is changed if it is + * different that the one of @p other. + */ + PointWrapper &operator= (const PointWrapper &other); + /** * Return the first component of the Point. */ @@ -68,12 +79,28 @@ namespace PyDealII */ void set_z(double z); + /** + * Return the dimension of the underlying Point. + */ + int get_dim() const; + /** * Return a pointer that can be casted to the underlying Point. */ void *get_point(); private: + /** + * Delete the underlying Point and free the memory. + */ + void clear(); + + + /** + * Copy @p other PointWrapper. + */ + void copy(const PointWrapper &other); + /** * Dimension of the Point. */ @@ -90,6 +117,14 @@ namespace PyDealII + inline + int PointWrapper::get_dim() const + { + return dim; + } + + + inline void *PointWrapper::get_point() { diff --git a/source/python/export_triangulation.cc b/source/python/export_triangulation.cc index 9ee2fd177c..f6a316fa3b 100644 --- a/source/python/export_triangulation.cc +++ b/source/python/export_triangulation.cc @@ -20,7 +20,7 @@ namespace PyDealII { // Macro to enable default arguments - BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_hyper_cube_overloads, generate_hyper_cube, 0, 3) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_hyper_cube_overloads, generate_hyper_cube, 1, 3) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_subdivided_hyper_cube_overloads, generate_subdivided_hyper_cube, 1, 3) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_hyper_rectangle_overloads, diff --git a/source/python/point_wrapper.cc b/source/python/point_wrapper.cc index 7a0214fb57..87cc48090e 100644 --- a/source/python/point_wrapper.cc +++ b/source/python/point_wrapper.cc @@ -42,29 +42,31 @@ namespace PyDealII + PointWrapper::PointWrapper(const PointWrapper &other) + { + copy(other); + } + + + PointWrapper::~PointWrapper() { - if (point != nullptr) - { - if (dim == 2) - { - // We cannot call delete on a void pointer so cast the void pointer back - // first. - dealii::Point<2> *tmp = static_cast*>(point); - delete tmp; - } - else - { - dealii::Point<3> *tmp = static_cast*>(point); - delete tmp; - } - point = nullptr; - } + clear(); dim = -1; } + PointWrapper &PointWrapper::operator= (const PointWrapper &other) + { + clear(); + copy(other); + + return *this; + } + + + double PointWrapper::get_x() const { if (dim == 2) @@ -124,4 +126,47 @@ namespace PyDealII AssertThrow(false, dealii::ExcMessage("The z coordinate is only available for three-dimensional points")); } + + + + + void PointWrapper::clear() + { + if (point != nullptr) + { + if (dim == 2) + { + // We cannot call delete on a void pointer so cast the void pointer back + // first. + dealii::Point<2> *tmp = static_cast*>(point); + delete tmp; + } + else + { + dealii::Point<3> *tmp = static_cast*>(point); + delete tmp; + } + point = nullptr; + } + } + + + + void PointWrapper::copy(const PointWrapper &other) + { + dim = other.dim; + + if (dim == 2) + { + dealii::Point<2> *other_point = static_cast*>(other.point); + point = new dealii::Point<2> ((*other_point)[0], (*other_point)[1]); + } + else if (dim == 3) + { + dealii::Point<3> *other_point = static_cast*>(other.point); + point = new dealii::Point<3> ((*other_point)[0], (*other_point)[1], (*other_point)[2]); + } + else + point = nullptr; + } } diff --git a/source/python/triangulation_wrapper.cc b/source/python/triangulation_wrapper.cc index 87080d078b..915a830553 100644 --- a/source/python/triangulation_wrapper.cc +++ b/source/python/triangulation_wrapper.cc @@ -44,8 +44,8 @@ namespace PyDealII void *triangulation) { // Cast the PointWrapper objects to Point - std::vector> points(dim); - for (int i=0; i> points(dim+1); + for (int i=0; i*>((wrapped_points[i]).get_point())); dealii::Triangulation *tria = @@ -76,6 +76,10 @@ namespace PyDealII const bool colorize, void *triangulation) { + AssertThrow(p1.get_dim() == dim, + dealii::ExcMessage("Dimension of p1 is not the same as the dimension of the Triangulation.")); + AssertThrow(p2.get_dim() == dim, + dealii::ExcMessage("Dimension of p2 is not the same as the dimension of the Triangulation.")); // Cast the PointWrapper object to Point dealii::Point point_1 = *(static_cast*>(p1.get_point())); dealii::Point point_2 = *(static_cast*>(p2.get_point())); @@ -95,6 +99,10 @@ namespace PyDealII const bool colorize, void *triangulation) { + AssertThrow(p1.get_dim() == dim, + dealii::ExcMessage("Dimension of p1 is not the same as the dimension of the Triangulation.")); + AssertThrow(p2.get_dim() == dim, + dealii::ExcMessage("Dimension of p2 is not the same as the dimension of the Triangulation.")); // Cast the PointWrapper object to Point dealii::Point point_1 = *(static_cast*>(p1.get_point())); dealii::Point point_2 = *(static_cast*>(p2.get_point())); @@ -229,10 +237,16 @@ namespace PyDealII void TriangulationWrapper::generate_simplex(boost::python::list &vertices) { + AssertThrow(boost::python::len(vertices) == dim+1, + dealii::ExcMessage("The number of vertices should be equal to dim+1.")); // Extract the PointWrapper object from the python list - std::vector wrapped_points(dim); - for (int i=0; i(vertices[i]); + std::vector wrapped_points(dim+1); + for (int i=0; i(vertices[i]); + AssertThrow(wrapped_points[i].get_dim() == dim, + dealii::ExcMessage("Point of wrong dimension.")); + } if (dim == 2) internal::generate_simplex<2>(wrapped_points, triangulation); @@ -271,6 +285,9 @@ namespace PyDealII PointWrapper &p2, const bool colorize) { + AssertThrow(boost::python::len(repetition_list) == dim, + dealii::ExcMessage("The list of repetitions must have the same length as the number of dimension.")); + // Extract the repetitions from the python list std::vector repetitions(dim); for (int i=0; i