From: Bruno Turcksin Date: Sun, 10 Sep 2017 21:22:13 +0000 (-0400) Subject: Add python wrappers to generate more meshes and to flatten triangulations X-Git-Tag: v9.0.0-rc1~1072^2~2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=138d20282b306d85afc7962bfbc81eecedff03b0;p=dealii.git Add python wrappers to generate more meshes and to flatten triangulations --- diff --git a/contrib/python-bindings/include/triangulation_wrapper.h b/contrib/python-bindings/include/triangulation_wrapper.h index d62f9c4823..4ddc5d6383 100644 --- a/contrib/python-bindings/include/triangulation_wrapper.h +++ b/contrib/python-bindings/include/triangulation_wrapper.h @@ -83,7 +83,7 @@ namespace python /** * Generate a coordinate-parallel brick from the two diagonally opposite - * corners points @p1 and @p2. + * corners points @p p1 and @p p2. */ void generate_hyper_rectangle(PointWrapper &p1, PointWrapper &p2, @@ -91,7 +91,7 @@ namespace python /** * Generate a coordinate-parallel brick from the two diagonally opposite - * corners points @p1 and @p2. In direction i, repetitions[i] cells are + * corners points @p p1 and @p p2. In direction i, repetitions[i] cells are * created. */ void generate_subdivided_hyper_rectangle(boost::python::list &repetitions, @@ -99,13 +99,156 @@ namespace python PointWrapper &p2, const bool colorize = false); + /** + * Like the previous function. However, here the first argument does not + * denote the number of subdivisions in each coordinate direction, but a + * sequence of step sizes for each coordinate direction. This function is + * therefore the right one to generate graded meshes where cells are + * concentrated in certains areas, rather than a uniformly subdidived mesh + * as the previous function generates. + */ + void generate_subdivided_steps_hyper_rectangle(boost::python::list &step_sizes, + PointWrapper &p1, + PointWrapper &p2, + const bool colorize = false); + + /** + * Like the previous function, but with the following twist: the @p + * material_id argument is a dim-dimensional array that, for each cell, + * indicates which material_id should be set. In addition, and this is the + * major new functionality, if the material_id of a cell is (-1), then that + * cell is deleted from the triangulation, i.e. the domain will have a void + * there. + */ + void generate_subdivided_material_hyper_rectangle(boost::python::list &spacing, + PointWrapper &p, + boost::python::list &material_id, + 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 + * subdivided_hyper_rectangle(). The argument @p holes specifies how many + * square holes the domain should have in each coordinate direction. The + * total number of mesh cells in that direction is then this number plus + * one. The number of holes in one direction must be at least one. + */ + void generate_cheese(boost::python::list &holes); + + /** + * A general quadrilateral in 2d or a general hexahedron in 3d. It is the + * responsibility of the user to provide the vertices in the right order + * (see the documentation of the GeometryInfo class) because the vertices + * are stored in the same order as they are given. It is also important to + * make that the volume of the cell is positive. If the argument @p colorize + * is false, all boundary indicators are set to zero ("not colorized") for + * 2d and 3d. If it is true, the boundary is colorized as in + * hyper_rectangle(). In 1d, the indicators are always colorized. + */ + void generate_general_cell(boost::python::list &vertices, + const bool colorize = false); + + /** + * A parallelogram. The first corner point is the origin. The @tparam dim + * adjacent points are the ones given in the second argument and the fourth + * point will be the sum of these two vectors. Colorizing is done in the + * same way as in hyper_rectangle(). + * @note This function is implemented in 2d only. + */ + void generate_parallelogram(boost::python::list &corners, + const bool colorize = false); + + /** + * A parallelepiped. The first corner point is the origin. The @tparam dim + * adjacent points are vectors describing the edges of the parallelepiped + * with respect to the origin. Additional points are sums of these dim + * vectors. Colorizing is done according to hyper_rectangle(). + * @note This function silently reorders the vertices on the cells to + * lexicographic ordering (see GridReordering::reoder_grid()). In other + * words, if reordering of the vertices does occur, the ordering of vertices + * in the array of @p corners will no longer refer to the same + * triangulation. + */ + void generate_parallelepiped(boost::python::list &corners, + const bool colorize = false); + + /** + * A subdivided parallelepiped. The first corner point is the origin. The + * @tparam dim adjacent points are vectors describing the edges of the + * parallelepiped with respect to the origin. Additional points are sums of + * these dim vectors. The variable @p n_subdivisions designates the number + * of subdivisions in each of the @tparam dim directions. Colorizing is odne + * according to hyper_rectangle(). + */ + void generate_fixed_subdivided_parallelepiped(const unsigned int n_subdivisions, + boost::python::list &corners, + const bool colorize = false); + + /** + * A subdivided parallelepided, i.e., the same as above, but where the + * number of subdivisions in each ot the @tparam dim directsions may vary. + * Colorizing is done according to hyper_rectangle(). + */ + void generate_varying_subdivided_parallelepiped(boost::python::list &n_subdivisions, + boost::python::list &corners, + const bool colorize = false); + + /** + * Hypercube with a layer of hypercubes around it. The first two parameters + * give the lower and upper bound of the inner hypercube in all coordinate + * directions. @p thickness marks the size of the layer cells. If the flag + * @p colorize is set, the outer cells get material id's according to the + * following scheme: extending over the inner cube (+/-) x-direction: 1/2. + * In y-direction 4/8, in z-direction 16/32. The cells at corners and edges + * (3d) get these values bitwise or'd. + */ + void generate_enclosed_hyper_cube(const double left = 0., + const double right = 1., + const double thickness = 1., + const bool colorize = false); + /** * Generate a hyperball, i.e. a circle or a ball around @p center with - * given @p radius. + * given @p radius. In order to avoid degenerate cells at the boundaries, + * the circle is triangulated by five cells, the ball by seven cells. The + * diameter of the center cell is chosen so that the aspect ratio of the + * boundary cells after one refinement is optimized. You should attach a + * SphericalManifold to the cells and faces for correct placement of + * vertices upon refinement and to be able to use higher order mappings. */ void generate_hyper_ball(PointWrapper ¢er, const double radius = 1.); + /** + * Generate a hyper sphere, i.e., a surface of a ball in @tparam spacedim + * dimensions. This function only exists for dim+1=spacedim in 2 and 3 space + * dimensions. You should attach a SphericalManifold to the cells and faces + * for correct placement of vertices upon refinement and to be able to use + * higher order mappings. + */ + void generate_hyper_sphere(PointWrapper ¢er, + const double radius = 1.); + + /** + * Generate a hyper-ball intersected with the positive orthant relate to @p + * center, which contains three elements in 2d and four in 3d. The boundary + * indicators for the final triangulations are 0 for the curved boundary + * and 1 for the cut plane. The appropiate boundary class is + * HyperBallBoundary. + */ + void generate_quarter_hyper_ball(PointWrapper ¢er, + const double radius = 1.); + + /** + * Generate a half hyper-ball around @p center, which contains four elements + * in 2d and 6 in 3d. The cut plane is perpendicular to the x-axis. The + * boundary indicators for the final triangulation are 0 for the curved + * boundary and 1 for the cut plane. The appropriate boundary class is + * HalfHyperBallBoundary, or HyperBallBoundary. + */ + void generate_half_hyper_ball(PointWrapper ¢er, + const double radius = 1.); + /** * Shift each vertex of the Triangulation by the given @p shift_list. */ @@ -117,6 +260,26 @@ namespace python */ void merge_triangulations(TriangulationWrapper &triangulation_1, TriangulationWrapper &triangulation_2); + + /** + * Create a new flat triangulation @param out_tria which contains a single + * level with all active cells of the input triangulation. If the spacedim + * are different, only the smalled spacedim components of the vertices are + * copied over. This is useful to create a Triangulation<2,3> out of a + * Triangulation<2,2>, or to project a Triangulation<2,3> into a + * Triangulation<2,2>, by neglecting the z component of the vertices. No + * internal checks are performed on the vertices, which are assumed to make + * sense topologically in the target spacedim dimensional space. If this is + * not the case, you will encounter problems when using the triangulation + * later on. All information about cell manifold_ids and material ids are + * copied from one triangulation to the other, and only the boundary + * manifold_ids and boundary_ids are copied over from the faces of the + * triangulation to the faces of @p out_tria. If you need to specify + * manifold ids on interior faces, they have to be specified manually after + * the triangulation is created. This function will fail the input + * Triangulation contains hanging nodes. + */ + void flatten_triangulation(TriangulationWrapper &tria_out); /** * Refine all the cells @p n times. diff --git a/contrib/python-bindings/source/export_triangulation.cc b/contrib/python-bindings/source/export_triangulation.cc index 3b6e3fb9f4..27e628bde4 100644 --- a/contrib/python-bindings/source/export_triangulation.cc +++ b/contrib/python-bindings/source/export_triangulation.cc @@ -34,8 +34,30 @@ namespace python generate_hyper_rectangle, 2, 3) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_subdivided_hyper_rectangle_overloads, generate_subdivided_hyper_rectangle, 3, 4) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_subdivided_steps_hyper_rectangle_overloads, + generate_subdivided_steps_hyper_rectangle, 3, 4) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_subdivided_material_hyper_rectangle_overloads, + generate_subdivided_material_hyper_rectangle, 3, 4) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_general_cell_overloads, + generate_general_cell, 1, 2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_parallelogram_overloads, + generate_parallelogram, 1, 2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_parallelepiped_overloads, + generate_parallelepiped, 1, 2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_fixed_subdivided_parallelepiped_overloads, + generate_fixed_subdivided_parallelepiped, 2, 3) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_varying_subdivided_parallelepiped_overloads, + generate_varying_subdivided_parallelepiped, 2, 3) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_enclosed_hyper_cube_overloads, + generate_enclosed_hyper_cube, 0, 4) BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_hyper_ball_overloads, generate_hyper_ball, 1, 2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_hyper_sphere_overloads, + generate_hyper_sphere, 1, 2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_quarter_hyper_ball_overloads, + generate_quarter_hyper_ball, 1, 2) + BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(generate_half_hyper_ball_overloads, + generate_half_hyper_ball, 1, 2) @@ -80,70 +102,227 @@ namespace python + const char generate_subdivided_steps_hyper_rectangle_docstring [] = + "Like the previous function. However, here the first argument does not \n" + "denote the number of subdivisions in each coordinate direction, but a \n" + "sequence of step sizes for each coordinate direction. This function is \n" + "therefore the right one to generate graded meshes where cells are \n" + "concentrated in certains areas, rather than a uniformly subdidived mesh\n" + "as the previous function generates. \n" + ; + + + + const char generate_subdivided_material_hyper_rectangle_docstring [] = + "Like the previous function, but with the following twist: the \n" + "material_id argument is a dim-dimensional array that, for each cell, \n" + "indicates which material_id should be set. In addition, and this is the\n" + "major new functionality, if the material_id of a cell is (-1), then \n" + "that cell is deleted from the triangulation, i.e. the domain will have \n" + "a void there. \n" + ; + + + + const char generate_cheese_docstring [] = + "Rectangular domain with rectangular pattern of holes. The domain itself\n" + "is rectangular, very much as if it had been generated by \n" + "subdivided_hyper_rectangle(). The argument holes specifies how many \n" + "square holes the domain should have in each coordinate direction. The \n" + "total number of mesh cells in that direction is then this number plus \n" + "one. The number of holes in one direction must be at least one. \n" + ; + + + + const char generate_general_cell_docstring [] = + "A general quadrilateral in 2d or a general hexahedron in 3d. It is the \n" + "responsibility of the user to provide the vertices in the right order \n" + "(see the documentation of the GeometryInfo class) because the vertices \n" + "are stored in the same order as they are given. It is also important to\n" + "make that the volume of the cell is positive. If the argument \n" + "colorize is false, all boundary indicators are set to zero (not \n" + "colorized) for 2d and 3d. If it is true, the boundary is colorized as \n" + "in hyper_rectangle(). In 1d, the indicators are always colorized. \n" + ; + + + + const char generate_parallelogram_docstring [] = + "A parallelogram. The first corner point is the origin. The dim \n" + "adjacent points are the ones given in the second argument and the \n" + "fourth point will be the sum of these two vectors. Colorizing is done \n" + "in the same way as in hyper_rectangle(). \n" + "Note: This function is implemented in 2d only. \n" + ; + + + + const char generate_parallelepiped_docstring [] = + "A parallelepiped. The first corner point is the origin. The dim \n" + "adjacent points are vectors describing the edges of the parallelepiped \n" + "with respect to the origin. Additional points are sums of these dim \n" + "vectors. Colorizing is done according to hyper_rectangle(). \n" + "Note: This function silently reorders the vertices on the cells to \n" + "lexicographic ordering (see GridReordering::reoder_grid()). In other \n" + "words, if reordering of the vertices does occur, the ordering of \n" + "vertices in the array of corners will no longer refer to the same \n" + "triangulation. \n" + ; + + + + const char generate_fixed_subdivided_parallelepiped_docstring [] = + "A subdivided parallelepiped. The first corner point is the origin. The \n" + "dim adjacent points are vectors describing the edges of the \n" + "parallelepiped with respect to the origin. Additional points are sums \n" + "of these dim vectors. The variable n_subdivisions designates the number\n" + "of subdivisions in each of the dim directions. Colorizing is odne \n" + "according to hyper_rectangle(). \n" + ; + + + + const char generate_varying_subdivided_parallelepiped_docstring [] = + "A subdivided parallelepided, i.e., the same as above, but where the \n" + "number of subdivisions in each ot the dim directsions may vary. \n" + "Colorizing is done according to hyper_rectangle(). \n" + ; + + + + const char generate_enclosed_hyper_cube_docstring [] = + "Hypercube with a layer of hypercubes around it. The first two \n" + "parameters give the lower and upper bound of the inner hypercube in all\n" + "coordinate directions. thickness marks the size of the layer cells. If \n" + "the flag colorize is set, the outer cells get material id's according \n" + "to the following scheme: extending over the inner cube (+/-) \n" + "x-direction: 1/2. In y-direction 4/8, in z-direction 16/32. The cells i\n" + "at corners and edges (3d) get these values bitwise or'd. \n" + ; + + + const char generate_hyper_ball_docstring [] = - "Generate a hyperball, i.e., a circle or a ball around center with \n" - "a given radius \n" + "Generate a hyperball, i.e. a circle or a ball around center with \n" + "given radius. In order to avoid degenerate cells at the boundaries, \n" + "the circle is triangulated by five cells, the ball by seven cells. The \n" + "diameter of the center cell is chosen so that the aspect ratio of the \n" + "boundary cells after one refinement is optimized. You should attach a \n" + "SphericalManifold to the cells and faces for correct placement of \n" + "vertices upon refinement and to be able to use higher order mappings. \n" + ; + + + + const char generate_hyper_sphere_docstring [] = + "Generate a hyper sphere, i.e., a surface of a ball in spacedim \n" + "dimensions. This function only exists for dim+1=spacedim in 2 and 3 \n" + "space dimensions. You should attach a SphericalManifold to the cells \n" + "and faces for correct placement of vertices upon refinement and to be \n" + "able to use higher order mappings. \n" + ; + + + + const char generate_quarter_hyper_ball_docstring [] = + "Generate a hyper-ball intersected with the positive orthant relate to \n" + "center, which contains three elements in 2d and four in 3d. The \n" + "boundary indicators for the final triangulations are 0 for the curved \n" + "boundary and 1 for the cut plane. The appropiate boundary class is \n" + "HyperBallBoundary. \n" + ; + + + + const char generate_half_hyper_ball_docstring [] = + "Generate a half hyper-ball around center, which contains four \n" + "elements in 2d and 6 in 3d. The cut plane is perpendicular to the \n" + "x-axis. The boundary indicators for the final triangulation are 0 for \n" + "the curved boundary and 1 for the cut plane. The appropriate boundary \n" + "class is HalfHyperBallBoundary, or HyperBallBoundary. \n" ; const char shift_docstring [] = - "Shift every vertex of the Triangulation by the gien shift vector \n" + "Shift every vertex of the Triangulation by the gien shift vector \n" ; const char merge_docstring [] = - "Given two triangulations, create the triangulation that contains \n" - "the cells of both triangulations \n" + "Given two triangulations, create the triangulation that contains \n" + "the cells of both triangulations \n" + ; + + + + const char flatten_triangulation_docstring [] = + "Create a new flat triangulation out_tria which contains a single \n" + "level with all active cells of the input triangulation. If the spacedim\n" + "are different, only the smalled spacedim components of the vertices are\n" + "copied over. This is useful to create a Triangulation<2,3> out of a \n" + "Triangulation<2,2>, or to project a Triangulation<2,3> into a \n" + "Triangulation<2,2>, by neglecting the z component of the vertices. No \n" + "internal checks are performed on the vertices, which are assumed to \n" + "make sense topologically in the target spacedim dimensional space. If \n" + "this is not the case, you will encounter problems when using the \n" + "triangulation later on. All information about cell manifold_ids and \n" + "material ids are copied from one triangulation to the other, and only \n" + "the boundary manifold_ids and boundary_ids are copied over from the \n" + "faces of the triangulation to the faces of out_tria. If you need to \n" + "specify manifold ids on interior faces, they have to be specified \n" + "manually after the triangulation is created. This function will fail \n" + "the input Triangulation contains hanging nodes. \n" ; const char refine_global_docstring [] = - "Refine all the cells times time \n" + "Refine all the cells times time \n" ; const char execute_coarsening_and_refinement_docstring [] = - "Execute both refinement and coarsening of the Triangulation \n" + "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" + "Return the list of active cell accessors of the Triangulation \n" ; const char write_docstring [] = - "Write the mesh to the output file according to the given data format. \n" - "The possible formats are: \n" - " - none \n" - " - dx \n" - " - gnuplot \n" - " - eps \n" - " - ucd \n" - " - xfig \n" - " - msh \n" - " - svg \n" - " - mathgl \n" - " - vtk \n" - " - vtu \n" + "Write the mesh to the output file according to the given data format. \n" + "The possible formats are: \n" + " - none \n" + " - dx \n" + " - gnuplot \n" + " - eps \n" + " - ucd \n" + " - xfig \n" + " - msh \n" + " - svg \n" + " - mathgl \n" + " - vtk \n" + " - vtu \n" ; const char save_docstring [] = - "Write the Triangulation to a file \n" + "Write the Triangulation to a file \n" ; const char load_docstring [] = - "Load the Triangulation from a file \n" + "Load the Triangulation from a file \n" ; @@ -182,11 +361,75 @@ namespace python boost::python::args("self", "repetitions", "p1", "p2", "colorize"), generate_subdivided_hyper_rectangle_docstring)) + .def("generate_subdivided_steps_hyper_rectangle", + &TriangulationWrapper::generate_subdivided_steps_hyper_rectangle, + generate_subdivided_steps_hyper_rectangle_overloads( + boost::python::args("self", "step_sizes", + "p1", "p2", "colorize"), + generate_subdivided_steps_hyper_rectangle_docstring)) + .def("generate_subdivided_material_hyper_rectangle", + &TriangulationWrapper::generate_subdivided_material_hyper_rectangle, + generate_subdivided_material_hyper_rectangle_overloads( + boost::python::args("self", "spacing", "p", + "material_id", "colorize"), + generate_subdivided_material_hyper_rectangle_docstring)) + .def("generate_cheese", + &TriangulationWrapper::generate_cheese, + generate_cheese_docstring, + boost::python::args("self", "holes")) + .def("generate_general_cell", + &TriangulationWrapper::generate_general_cell, + generate_general_cell_overloads( + boost::python::args("self", "vertices", "colorize"), + generate_general_cell_docstring)) + .def("generate_parallelogram", + &TriangulationWrapper::generate_parallelogram, + generate_parallelogram_overloads( + boost::python::args("self", "corners", "colorize"), + generate_parallelogram_docstring)) + .def("generate_parallelepiped", + &TriangulationWrapper::generate_parallelepiped, + generate_parallelepiped_overloads( + boost::python::args("self", "corners", "colorize"), + generate_parallelepiped_docstring)) + .def("generate_fixed_subdivided_parallelepiped", + &TriangulationWrapper::generate_fixed_subdivided_parallelepiped, + generate_fixed_subdivided_parallelepiped_overloads( + boost::python::args("self", "n_subdivisions", + "corners", "colorize"), + generate_fixed_subdivided_parallelepiped_docstring)) + .def("generate_varying_subdivided_parallelepiped", + &TriangulationWrapper::generate_varying_subdivided_parallelepiped, + generate_varying_subdivided_parallelepiped_overloads( + boost::python::args("self", "n_subdivisions", + "corners", "colorize"), + generate_varying_subdivided_parallelepiped_docstring)) + .def("generate_enclosed_hyper_cube", + &TriangulationWrapper::generate_enclosed_hyper_cube, + generate_enclosed_hyper_cube_overloads( + boost::python::args("self", "left", "right", + "thickness", "colorize"), + generate_enclosed_hyper_cube_docstring)) .def("generate_hyper_ball", &TriangulationWrapper::generate_hyper_ball, generate_hyper_ball_overloads( boost::python::args("self", "center", "radius"), generate_hyper_ball_docstring)) + .def("generate_hyper_sphere", + &TriangulationWrapper::generate_hyper_sphere, + generate_hyper_sphere_overloads( + boost::python::args("self", "center", "radius"), + generate_hyper_sphere_docstring)) + .def("generate_quarter_hyper_ball", + &TriangulationWrapper::generate_quarter_hyper_ball, + generate_quarter_hyper_ball_overloads( + boost::python::args("self", "center", "radius"), + generate_quarter_hyper_ball_docstring)) + .def("generate_half_hyper_ball", + &TriangulationWrapper::generate_half_hyper_ball, + generate_half_hyper_ball_overloads( + boost::python::args("self", "center", "radius"), + generate_half_hyper_ball_docstring)) .def("shift", &TriangulationWrapper::shift, shift_docstring, @@ -195,6 +438,10 @@ namespace python &TriangulationWrapper::merge_triangulations, merge_docstring, boost::python::args("self", "triangulation_1", "triangulation_2")) + .def("flatten_triangulation", + &TriangulationWrapper::flatten_triangulation, + flatten_triangulation_docstring, + boost::python::args("self", "tria_out")) .def("refine_global", &TriangulationWrapper::refine_global, refine_global_docstring, diff --git a/contrib/python-bindings/source/triangulation_wrapper.cc b/contrib/python-bindings/source/triangulation_wrapper.cc index 39a27c6106..753587c741 100644 --- a/contrib/python-bindings/source/triangulation_wrapper.cc +++ b/contrib/python-bindings/source/triangulation_wrapper.cc @@ -18,6 +18,7 @@ #ifdef DEAL_II_WITH_CXX11 #include +#include #include #include #include @@ -123,6 +124,174 @@ namespace python + template + void generate_subdivided_steps_hyper_rectangle(const std::vector> &step_sizes, + PointWrapper &p1, + PointWrapper &p2, + const bool colorize, + void *triangulation) + { + AssertThrow(p1.get_dim() == dim, + ExcMessage("Dimension of p1 is not the same as the dimension of the Triangulation.")); + AssertThrow(p2.get_dim() == dim, + ExcMessage("Dimension of p2 is not the same as the dimension of the Triangulation.")); + // Cast the PointWrapper object to Point + Point point_1 = *(static_cast*>(p1.get_point())); + Point point_2 = *(static_cast*>(p2.get_point())); + + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::subdivided_hyper_rectangle(*tria, step_sizes, point_1, + point_2, colorize); + } + + + + template + void generate_subdivided_material_hyper_rectangle(const std::vector> &spacing, + PointWrapper &p, + const Table &material_ids, + const bool colorize, + void *triangulation) + { + AssertThrow(p.get_dim() == dim, + ExcMessage("Dimension of p is not the same as the dimension of the Triangulation.")); + // Cast the PointWrapper object to Point + Point point = *(static_cast*>(p.get_point())); + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::subdivided_hyper_rectangle(*tria, spacing, point, + material_ids, colorize); + } + + + + template + void generate_cheese(const std::vector &holes, + void *triangulation) + { + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::cheese(*tria, holes); + } + + + + template + void generate_general_cell(std::vector &wrapped_points, + const bool colorize, + void *triangulation) + { + // Cast the PointWrapper objects to Point + const unsigned int size = wrapped_points.size(); + std::vector> points(size); + for (unsigned int i=0; i*>((wrapped_points[i]).get_point())); + + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::general_cell(*tria, points, colorize); + } + + + + template + void generate_parallelogram(std::vector &wrapped_points, + const bool colorize, + void *triangulation) + { + // Cast the PointWrapper objects to Point + Point points[dim]; + for (unsigned int i=0; i*>((wrapped_points[i]).get_point())); + + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::parallelogram(*tria, points, colorize); + } + + + + template + void generate_parallelepiped(std::vector &wrapped_points, + const bool colorize, + void *triangulation) + { + // Cast the PointWrapper objects to Point + Point points[dim]; + for (unsigned int i=0; i*>((wrapped_points[i]).get_point())); + + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::parallelepiped(*tria, points, colorize); + } + + + + template + void generate_fixed_subdivided_parallelepiped(unsigned int n_subdivisions, + std::vector &wrapped_points, + const bool colorize, + void *triangulation) + { + // Cast the PointWrapper objects to Point + Point points[dim]; + for (unsigned int i=0; i*>((wrapped_points[i]).get_point())); + + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::subdivided_parallelepiped(*tria, n_subdivisions, points, colorize); + } + + + + template + void generate_varying_subdivided_parallelepiped(std::vector &n_subdivisions, + std::vector &wrapped_points, + const bool colorize, + void *triangulation) + { + // Cast the PointWrapper objects to Point + Point points[dim]; + unsigned int subdivisions[dim]; + for (unsigned int i=0; i*>((wrapped_points[i]).get_point())); + subdivisions[i] = n_subdivisions[i]; + } + + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::subdivided_parallelepiped(*tria, subdivisions, points, colorize); + } + + + + template + void generate_enclosed_hyper_cube(const double left, + const double right, + const double thickness, + const double colorize, + void *triangulation) + { + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::enclosed_hyper_cube(*tria, left, right, thickness, colorize); + } + + + template void generate_hyper_ball(PointWrapper ¢er, const double radius, @@ -140,6 +309,57 @@ namespace python + template + void generate_hyper_sphere(PointWrapper ¢er, + const double radius, + void *triangulation) + { + // Cast the PointWrapper object to Point + Point center_point = *(static_cast*>( + center.get_point())); + + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::hyper_sphere(*tria, center_point, radius); + } + + + + template + void generate_quarter_hyper_ball(PointWrapper ¢er, + const double radius, + void *triangulation) + { + // Cast the PointWrapper object to Point + Point center_point = *(static_cast*>( + center.get_point())); + + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::quarter_hyper_ball(*tria, center_point, radius); + } + + + + template + void generate_half_hyper_ball(PointWrapper ¢er, + const double radius, + void *triangulation) + { + // Cast the PointWrapper object to Point + Point center_point = *(static_cast*>( + center.get_point())); + + Triangulation *tria = + static_cast*>(triangulation); + tria->clear(); + GridGenerator::half_hyper_ball(*tria, center_point, radius); + } + + + template void shift(boost::python::list &shift_list, void *triangulation) @@ -176,6 +396,18 @@ namespace python + template + void flatten_triangulation(void *triangulation, TriangulationWrapper &tria_out) + { + Triangulation *tria = + static_cast*>(triangulation); + Triangulation *tria_2 = + static_cast*>(tria_out.get_triangulation()); + GridGenerator::flatten_triangulation(*tria, *tria_2); + } + + + template boost::python::list active_cells(TriangulationWrapper &triangulation_wrapper) { @@ -393,6 +625,225 @@ namespace python + void TriangulationWrapper::generate_subdivided_steps_hyper_rectangle(boost::python::list &step_sizes_list, + PointWrapper &p1, + PointWrapper &p2, + const bool colorize) + { + AssertThrow(spacedim == dim, + ExcMessage("This function is only implemented for dim equal to spacedim.")); + AssertThrow(boost::python::len(step_sizes_list) == dim, + ExcMessage("The list of step_sizes must have the same length as the number of dimension.")); + + // Extract the step sizes from the python list + std::vector> step_sizes(dim); + for (int i=0; i(step_sizes_list[i][j]); + } + + if (dim == 2) + internal::generate_subdivided_steps_hyper_rectangle<2>(step_sizes, + p1, p2, colorize, triangulation); + else + internal::generate_subdivided_steps_hyper_rectangle<3>(step_sizes, + p1, p2, colorize, triangulation); + } + + + + void TriangulationWrapper::generate_subdivided_material_hyper_rectangle(boost::python::list &spacing_list, + PointWrapper &p, + boost::python::list &material_id_list, + const bool colorize) + { + AssertThrow(spacedim == dim, + ExcMessage("This function is only implemented for dim equal to spacedim.")); + AssertThrow(boost::python::len(spacing_list) == dim, + ExcMessage("The list of spacing must have the same length as the number of dimension.")); + + // Extract the spacing and the material ID from the python list + std::vector> spacing(dim); + for (int i=0; i(spacing_list[i][j]); + } + if (dim == 2) + { + const unsigned int index_0 = boost::python::len(material_id_list); + const unsigned int index_1 = boost::python::len(material_id_list[0]); + Table<2, types::material_id> material_ids(index_0, index_1); + for (unsigned int i=0; i because boost will throw + // an exception if we try to extract -1 + material_ids[i][j] = boost::python::extract(material_id_list[i][j]); + + internal::generate_subdivided_material_hyper_rectangle<2>(spacing, p, + material_ids, colorize, triangulation); + } + else + { + const unsigned int index_0 = boost::python::len(material_id_list); + const unsigned int index_1 = boost::python::len(material_id_list[0]); + const unsigned int index_2 = boost::python::len(material_id_list[0][0]); + Table<3, types::material_id> material_ids(index_0, index_1, index_2); + for (unsigned int i=0; i(material_id_list[i][j][k]); + internal::generate_subdivided_material_hyper_rectangle<3>(spacing, p, + material_ids, colorize, triangulation); + } + } + + + + void TriangulationWrapper::generate_cheese(boost::python::list &holes_list) + { + const unsigned int size = boost::python::len(holes_list); + std::vector holes(size); + for (unsigned int i=0; i(holes_list[i]); + + if ((dim == 2) && (spacedim == 2)) + internal::generate_cheese<2,2>(holes, triangulation); + else if ((dim == 2) && (spacedim == 3)) + internal::generate_cheese<2,3>(holes, triangulation); + else + internal::generate_cheese<3,3>(holes, triangulation); + } + + + + void TriangulationWrapper::generate_general_cell(boost::python::list &vertices, + const bool colorize) + { + AssertThrow(spacedim == dim, + ExcMessage("This function is only implementd for dim equal to spacedim.")); + // Extract the PointWrapper object from the python list + const int size = boost::python::len(vertices); + AssertThrow(size > 0, ExcMessage("The vertices list is empty.")); + std::vector wrapped_points(size); + for (int i=0; i(vertices[i]); + if (dim == 2) + internal::generate_general_cell<2>(wrapped_points, colorize, triangulation); + else + internal::generate_general_cell<3>(wrapped_points, colorize, triangulation); + } + + + + void TriangulationWrapper::generate_parallelogram(boost::python::list &corners, + const bool colorize) + { + AssertThrow(spacedim == dim, + ExcMessage("This function is only implemented for dim equal to spacedim.")); + // Extract the PointWrapper object from the python list + AssertThrow(boost::python::len(corners) == dim, + ExcMessage("The list of corners must have the same length as the number of dimension.")); + std::vector wrapped_points(dim); + for (int i=0; i(corners[i]); + if (dim == 2) + internal::generate_parallelogram<2>(wrapped_points, colorize, triangulation); + else + internal::generate_parallelogram<3>(wrapped_points, colorize, triangulation); + } + + + + void TriangulationWrapper::generate_parallelepiped(boost::python::list &corners, + const bool colorize) + { + AssertThrow(spacedim == dim, + ExcMessage("This function is only implemented for dim equal to spacedim.")); + // Extract the PointWrapper object from the python list + AssertThrow(boost::python::len(corners) == dim, + ExcMessage("The list of corners must have the same length as the number of dimension.")); + std::vector wrapped_points(dim); + for (int i=0; i(corners[i]); + if (dim == 2) + internal::generate_parallelepiped<2>(wrapped_points, colorize, triangulation); + else + internal::generate_parallelepiped<3>(wrapped_points, colorize, triangulation); + } + + + + void TriangulationWrapper::generate_fixed_subdivided_parallelepiped( + const unsigned int n_subdivisions, + boost::python::list &corners, + const bool colorize) + { + AssertThrow(spacedim == dim, + ExcMessage("This function is only implemented for dim equal to spacedim.")); + // Extract the PointWrapper object from the python list + AssertThrow(boost::python::len(corners) == dim, + ExcMessage("The list of corners must have the same length as the number of dimension.")); + std::vector wrapped_points(dim); + for (int i=0; i(corners[i]); + if ((dim == 2) && (spacedim == 2)) + internal::generate_fixed_subdivided_parallelepiped<2>(n_subdivisions, + wrapped_points, colorize, triangulation); + else + internal::generate_fixed_subdivided_parallelepiped<3>(n_subdivisions, + wrapped_points, colorize, triangulation); + } + + + + void TriangulationWrapper::generate_varying_subdivided_parallelepiped( + boost::python::list &n_subdivisions, + boost::python::list &corners, + const bool colorize) + { + AssertThrow(spacedim == dim, + ExcMessage("This function is only implemented for dim equal to spacedim.")); + // Extract the subdivisions from the python list + AssertThrow(boost::python::len(n_subdivisions) == dim, + ExcMessage("The list of subdivisions must have the same length as the number of dimension.")); + std::vector subdivisions(dim); + for (int i=0; i(n_subdivisions[i]); + // Extract the PointWrapper object from the python list + AssertThrow(boost::python::len(corners) == dim, + ExcMessage("The list of corners must have the same length as the number of dimension.")); + std::vector wrapped_points(dim); + for (int i=0; i(corners[i]); + if (dim == 2) + internal::generate_varying_subdivided_parallelepiped<2>(subdivisions, + wrapped_points, colorize, triangulation); + else + internal::generate_varying_subdivided_parallelepiped<3>(subdivisions, + wrapped_points, colorize, triangulation); + } + + + + void TriangulationWrapper::generate_enclosed_hyper_cube(const double left, + const double right, + const double thickness, + const bool colorize) + { + AssertThrow(spacedim == dim, + ExcMessage("This function is only implemented for dim equal to spacedim.")); + if (dim == 2) + internal::generate_enclosed_hyper_cube<2>(left, right, thickness, colorize, triangulation); + else + internal::generate_enclosed_hyper_cube<3>(left, right, thickness, colorize, triangulation); + } + + + void TriangulationWrapper::generate_hyper_ball(PointWrapper ¢er, const double radius) { @@ -405,6 +856,40 @@ namespace python } + void TriangulationWrapper::generate_hyper_sphere(PointWrapper ¢er, + const double radius) + { + AssertThrow(spacedim == dim+1, + ExcMessage("This function is only implemented for spacedim equal to dim+1.")); + internal::generate_hyper_sphere<2,3>(center, radius, triangulation); + } + + + + void TriangulationWrapper::generate_quarter_hyper_ball(PointWrapper ¢er, + const double radius) + { + AssertThrow(dim == spacedim, + ExcMessage("This function is only implemented for dim equal to spacedim.")); + if (dim == 2) + internal::generate_quarter_hyper_ball<2>(center, radius, triangulation); + else + internal::generate_quarter_hyper_ball<3>(center, radius, triangulation); + } + + + void TriangulationWrapper::generate_half_hyper_ball(PointWrapper ¢er, + const double radius) + { + AssertThrow(dim == spacedim, + ExcMessage("This function is only implemented for dim equal to spacedim.")); + if (dim == 2) + internal::generate_half_hyper_ball<2>(center, radius, triangulation); + else + internal::generate_half_hyper_ball<3>(center, radius, triangulation); + } + + void TriangulationWrapper::shift(boost::python::list &shift_list) { @@ -442,6 +927,24 @@ namespace python + void TriangulationWrapper::flatten_triangulation(TriangulationWrapper &tria_out) + { + AssertThrow(dim == tria_out.get_dim(), + ExcMessage("The Triangulation and tria_out should have the same dimension.")); + AssertThrow(spacedim >= tria_out.get_spacedim(), + ExcMessage("The Triangulation should have a spacedim greater or equal " + "to the spacedim of tria_out.")); + int spacedim_out = tria_out.get_spacedim(); + if ((dim == 2) && (spacedim == 2) && (spacedim_out == 2)) + internal::flatten_triangulation<2,2,2>(triangulation, tria_out); + else if ((dim == 2) && (spacedim == 3) && (spacedim_out == 2)) + internal::flatten_triangulation<2,3,2>(triangulation, tria_out); + else + internal::flatten_triangulation<3,3,3>(triangulation, tria_out); + } + + + void TriangulationWrapper::refine_global(const unsigned int n) { if ((dim == 2) && (spacedim == 2))