that are still referenced in these video lectures. For
example, the step-1 code shown in video lecture 5 uses a class
HyperShellBoundary which was replaced with SphericalManifold class
-later on. However, in spite of such kind of details the content of the
-lectures is still very relevant.
+later on. Additionally, as of deal.II version 9.0, GridGenerator::hyper_shell()
+now automatically attaches a SphericalManifold to the Triangulation. Otherwise
+the rest of the lecture material is relevant.
<h3> What this program does </h3>
geometries altogether. While for complex geometries there is no way around
using meshes obtained from mesh generators, there is a good number of
geometries for which deal.II can create meshes using the functions in the
-GridGenerator namespace. Take a look at what it provides and see how it could
-be used in a program like this.
-
-We also discuss a variety of other ways to create and manipulate meshes to
-step-49.
+GridGenerator namespace. Many of these geometries (such as the one used in this
+example program) contain cells with curved faces: put another way, we expect the
+new vertices placed on the boundary to lie along a circle. deal.II handles complex
+geometries with the Manifold class (and classes inheriting from it); in particular,
+the functions in GridGenerator corresponding to non-Cartesian grids (such as
+GridGenerator::hyper_shell or GridGenerator::truncated_cone) attach a Manifold
+object to the part of the triangulation that should be curved (SphericalManifold
+and CylindricalManifold, respectively) and use another manifold on the parts that
+should be flat (FlatManifold). See the documentation
+of Manifold or the @ref manifold "manifold module" for descriptions of the design
+philosophy and interfaces of these classes. Take a look at what they provide and
+see how they could be used in a program like this.
+
+We also discuss a variety of other ways to create and manipulate meshes (and
+describe the process of attaching Manifolds) in step-49.
<h4> Comments about programming and debugging </h4>
// straight lines, and all cells are bi-linear quads or tri-linear
// hexes, and that they are defined by the cells of the coarse grid
// (which we just created). Unless we do something special, when new
- // points need to be introduced; the domain is assumed to be
+ // points need to be introduced the domain is assumed to be
// delineated by the straight lines of the coarse mesh, and new
// points will simply be in the middle of the surrounding ones.
// Here, however, we know that the domain is curved, and we would
// triangulation to use a particular "manifold object" for all
// places with this manifold indicator. How exactly this works is
// not important at this point (you can read up on it in step-53 and
- // @ref manifold). Here, for simplicity, we will choose the manifold
- // id to be zero. By default, all cells and faces of the
- // Triangulation have their manifold_id set to
+ // @ref manifold). The functions in GridGenerator handle this for us in most
+ // circumstances: they attach the correct manifold to a domain so that when
+ // the triangulation is refined new cells are placed in the correct
+ // places. In the present case GridGenerator::hyper_shell attaches a
+ // SphericalManifold to all cells: this causes cells to be refined with
+ // calculations in spherical coordinates (so new cells have edges that are
+ // either radial or lie along concentric circles around the origin).
+ //
+ // By default (i.e., for a Triangulation created by hand or without a call
+ // to a GridGenerator function like GridGenerator::hyper_shell or
+ // GridGenerator::hyper_ball), all cells and
+ // faces of the Triangulation have their manifold_id set to
// numbers::invalid_manifold_id, which is the default if you want a
// manifold that produces straight edges, but you can change this
// number for individual cells and faces. In that case, the curved
// edges is implied. (Manifold indicators are a slightly complicated
// topic; if you're confused about what exactly is happening here,
// you may want to look at the @ref GlossManifoldIndicator "glossary
- // entry on this topic".)
- const SphericalManifold<2> manifold_description(center);
- triangulation.set_manifold (0, manifold_description);
- triangulation.set_all_manifold_ids(0);
-
+ // entry on this topic".) Since the default chosen by
+ // GridGenerator::hyper_shell is reasonable we leave things alone.
+ //
// In order to demonstrate how to write a loop over all cells, we will
// refine the grid in five steps towards the inner circle of the domain:
for (unsigned int step=0; step<5; ++step)
if (cycle == 0)
{
GridGenerator::hyper_ball (triangulation);
-
- static const SphericalManifold<dim> boundary;
- triangulation.set_all_manifold_ids_on_boundary(0);
- triangulation.set_manifold (0, boundary);
-
triangulation.refine_global (1);
}
else
// This is the function that produced the circular grid in the previous step-1
// example program with fewer refinements steps. The sole difference is that it
// returns the grid it produces via its argument.
-//
-// The details of what the function does are explained in step-1. The only
-// thing we would like to comment on is this:
-//
-// Since we want to export the triangulation through this function's
-// parameter, we need to make sure that the manifold object lives at least as
-// long as the triangulation does. However, in step-1, the manifold object is
-// a local variable, and it would be deleted at the end of the function, which
-// is too early. We avoid the problem by declaring it 'static' which makes
-// sure that the object is initialized the first time control the program
-// passes this point, but at the same time assures that it lives until the end
-// of the program.
void make_grid (Triangulation<2> &triangulation)
{
const Point<2> center (1,0);
center, inner_radius, outer_radius,
5 );
- static const SphericalManifold<2> manifold_description(center);
- triangulation.set_manifold (0, manifold_description);
- triangulation.set_all_manifold_ids(0);
-
for (unsigned int step=0; step<3; ++step)
{
for (auto cell: triangulation.active_cell_iterators())
{
const Point<dim> center;
GridGenerator::hyper_ball (triangulation, center, 1.);
- static const SphericalManifold<dim> boundary_description (center);
- triangulation.set_all_manifold_ids_on_boundary(0);
- triangulation.set_manifold (0,boundary_description);
triangulation.refine_global (7);
time_step = GridTools::minimal_cell_diameter(triangulation) /
}
// For the circle part of the transducer lens, a SphericalManifold object
// is used (which, of course, in 2D just represents a circle), with center
- // computed as above. By marking this object as <code>static</code>, we
- // ensure that it lives until the end of the program and thereby longer
- // than the triangulation object we will associate with it. We then assign
- // this boundary-object to the part of the boundary with boundary indicator 1:
- static const SphericalManifold<dim> boundary(focal_point);
- triangulation.set_manifold(1, boundary);
+ // computed as above.
+ triangulation.set_manifold(1, SphericalManifold<dim>(focal_point));
// Now global refinement is executed. Cells near the transducer location
// will be automatically refined according to the circle shaped boundary
const Point<dim> center(0, 0, 0);
const double radius = 0.8;
GridGenerator::half_hyper_ball(triangulation, center, radius);
+ // Since we will attach a different manifold below, we immediately
+ // clear the default manifold description:
+ triangulation.reset_all_manifolds();
GridTools::transform(&rotate_half_sphere, triangulation);
GridTools::shift(Point<dim>(0.5, 0.5, 0.5), triangulation);
- static SphericalManifold<dim> manifold_description(Point<dim>(0.5, 0.5, 0.5));
+ SphericalManifold<dim> manifold_description(Point<dim>(0.5, 0.5, 0.5));
GridTools::copy_boundary_to_manifold_id(triangulation);
triangulation.set_manifold(0, manifold_description);
}
MPI_Comm mpi_communicator;
- SphericalManifold<dim> manifold;
parallel::distributed::Triangulation<dim> triangulation;
FESystem<dim> fe;
DoFHandler<dim> dof_handler;
// parallel::distributed::Triangulation::add_periodicity.
triangulation.add_periodicity(periodicity_vector);
- triangulation.set_all_manifold_ids(1);
- triangulation.set_manifold(1, manifold);
-
triangulation.refine_global (4-dim);
}
{
GridGenerator::hyper_ball (triangulation);
//GridGenerator::hyper_cube (triangulation, -1, 1);
-
- static const SphericalManifold<dim> boundary;
- triangulation.set_all_manifold_ids_on_boundary(0);
- triangulation.set_manifold (0, boundary);
-
triangulation.refine_global (2);
}
else