@verbatim
Surface mesh has 1280 cells.
Surface mesh has 5185 degrees of freedom.
-H1 error = 0.0221245
+H1 error = 0.0217136
@endverbatim
@verbatim
Surface mesh has 5120 cells.
Surface mesh has 20609 degrees of freedom.
-H1 error = 0.00552639
+H1 error = 0.00543481
@endverbatim
This is what we expect: make the mesh size smaller by a factor of two and the
elements). The full sequence of errors from one to five refinements looks like
this, neatly following the theoretically predicted pattern:
@verbatim
-0.360759
-0.0888008
-0.0221245
-0.00552639
-0.0013813
+0.339438
+0.0864385
+0.0217136
+0.00543481
+0.00135913
@endverbatim
Finally, the program produces graphical output that we can visualize. Here is
<img src="https://www.dealii.org/images/steps/developer/step-38.warp-2.png" alt="">
-The way to produce such a mesh is by using the GridTools::transform
+The way to produce such a mesh is by using the GridTools::transform()
function. It needs a way to transform each individual mesh point to a
different position. Let us here use the following, rather simple function
(remember: stretch in one direction, jumble in the other two):
@code
template <int spacedim>
-Point<spacedim> warp (const Point<spacedim> &p)
+Point<spacedim> warp(const Point<spacedim> &p)
{
Point<spacedim> q = p;
q[spacedim-1] *= 10;
@code
template <int spacedim>
-void LaplaceBeltrami<spacedim>::make_grid_and_dofs ()
+void LaplaceBeltrami<spacedim>::make_grid_and_dofs()
{
- triangulation.set_manifold (0, SphericalManifold<dim,spacedim>());
-
{
Triangulation<spacedim> volume_mesh;
GridGenerator::half_hyper_ball(volume_mesh);
- volume_mesh.set_manifold (0, SphericalManifold<spacedim>);
- volume_mesh.refine_global (4);
+ volume_mesh.refine_global(4);
std::set<types::boundary_id> boundary_ids;
- boundary_ids.insert (0);
+ boundary_ids.insert(0);
- GridGenerator::extract_boundary_mesh (volume_mesh, triangulation,
- boundary_ids);
- triangulation.set_manifold (1); /* ** */
- triangulation.set_manifold (0); /* ** */
- GridTools::transform (&warp<spacedim>, triangulation); /* ** */
+ GridGenerator::extract_boundary_mesh(volume_mesh, triangulation,
+ boundary_ids);
+ GridTools::transform(&warp<spacedim>, triangulation); /* ** */
std::ofstream x("x"), y("y");
- GridOut().write_gnuplot (volume_mesh, x);
- GridOut().write_gnuplot (triangulation, y);
+ GridOut().write_gnuplot(volume_mesh, x);
+ GridOut().write_gnuplot(triangulation, y);
}
std::cout << "Surface mesh has " << triangulation.n_active_cells()
<< " cells."
<< std::endl;
-
...
+}
@endcode
-Note that the only essential addition has been the three lines marked with
+Note that the only essential addition is the line marked with
asterisks. It is worth pointing out one other thing here, though: because we
detach the manifold description from the surface mesh, whenever we use a
mapping object in the rest of the program, it has no curves boundary
other differences to what's in step-38 is that we changed the right hand side
to $f(\mathbf x)=\sin x_3$ and the boundary values (through the
<code>Solution</code> class) to $u(\mathbf x)|_{\partial\Omega}=\cos x_3$. Of
-course, we now non longer know the exact solution, so the computation of the
+course, we now no longer know the exact solution, so the computation of the
error at the end of <code>LaplaceBeltrami::run</code> will yield a meaningless
number.