From ee7194f44c7ea7accb9eb997d3c3ec4a690ec5fb Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Fri, 7 Feb 2020 11:09:02 -0700 Subject: [PATCH] Convert step-30 from using eps/gnuplot to svg/vtu. The figures as currently used are actually quite ugly. We can do substantially better. While there, also clean up the function that creates output a bit. --- examples/step-30/doc/results.dox | 218 ++++++++++++++++++++----------- examples/step-30/step-30.cc | 62 ++++----- 2 files changed, 169 insertions(+), 111 deletions(-) diff --git a/examples/step-30/doc/results.dox b/examples/step-30/doc/results.dox index b18d042a2b..4a6feee8b6 100644 --- a/examples/step-30/doc/results.dox +++ b/examples/step-30/doc/results.dox @@ -1,125 +1,186 @@

Results

-The output of this program consist of the console output, the eps -files containing the grids, and the grids and solutions given in gnuplot format. +The output of this program consist of the console output, the SVG +files containing the grids, and the solutions given in VTU format. @code Performing a 2D run with isotropic refinement... ------------------------------------------------ Cycle 0: Number of active cells: 128 Number of degrees of freedom: 512 -Time of assemble_system: 0.040003 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Time of assemble_system: 0.092049 + Writing grid to ... + Writing solution to ... + Cycle 1: Number of active cells: 239 Number of degrees of freedom: 956 -Time of assemble_system: 0.072005 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Time of assemble_system: 0.109519 + Writing grid to ... + Writing solution to ... + Cycle 2: Number of active cells: 491 Number of degrees of freedom: 1964 -Time of assemble_system: 0.144009 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Time of assemble_system: 0.08303 + Writing grid to ... + Writing solution to ... + Cycle 3: Number of active cells: 1031 Number of degrees of freedom: 4124 -Time of assemble_system: 0.296019 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Time of assemble_system: 0.278987 + Writing grid to ... + Writing solution to ... + Cycle 4: Number of active cells: 2027 Number of degrees of freedom: 8108 -Time of assemble_system: 0.576036 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Time of assemble_system: 0.305869 + Writing grid to ... + Writing solution to ... + Cycle 5: Number of active cells: 4019 Number of degrees of freedom: 16076 -Time of assemble_system: 1.13607 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Time of assemble_system: 0.47616 + Writing grid to ... + Writing solution to ... + Performing a 2D run with anisotropic refinement... -------------------------------------------------- Cycle 0: Number of active cells: 128 Number of degrees of freedom: 512 -Time of assemble_system: 0.040003 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Time of assemble_system: 0.052866 + Writing grid to ... + Writing solution to ... + Cycle 1: Number of active cells: 171 Number of degrees of freedom: 684 -Time of assemble_system: 0.048003 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Time of assemble_system: 0.050917 + Writing grid to ... + Writing solution to ... + Cycle 2: Number of active cells: 255 Number of degrees of freedom: 1020 -Time of assemble_system: 0.072005 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Time of assemble_system: 0.064132 + Writing grid to ... + Writing solution to ... + Cycle 3: - Number of active cells: 397 - Number of degrees of freedom: 1588 -Time of assemble_system: 0.16401 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Number of active cells: 394 + Number of degrees of freedom: 1576 + Time of assemble_system: 0.119849 + Writing grid to ... + Writing solution to ... + Cycle 4: - Number of active cells: 658 - Number of degrees of freedom: 2632 -Time of assemble_system: 0.192012 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Number of active cells: 648 + Number of degrees of freedom: 2592 + Time of assemble_system: 0.218244 + Writing grid to ... + Writing solution to ... + Cycle 5: - Number of active cells: 1056 - Number of degrees of freedom: 4224 -Time of assemble_system: 0.304019 -Writing grid to ... -Writing grid to ... -Writing solution to ... + Number of active cells: 1030 + Number of degrees of freedom: 4120 + Time of assemble_system: 0.128121 + Writing grid to ... + Writing solution to ... @endcode This text output shows the reduction in the number of cells which results from the successive application of anisotropic refinement. After the last refinement -step the savings have accumulated so much, that almost four times as many cells -and thus dofs are needed in the isotropic case. The time needed for assembly +step the savings have accumulated so much that almost four times as many cells +and thus degrees of freedom are needed in the isotropic case. The time needed for assembly scales with a similar factor. -Now we show the solutions on the mesh after one and after five adaptive -refinement steps for both the isotropic (left) and anisotropic refinement -algorithms (right). +The first interesting part is of course to see how the meshes look like. +On the left are the isotropically refined ones, on the right the +anisotropic ones (colors indicate the refinement level of cells): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +The other interesting thing is, of course, to see the solution on these +two sequences of meshes. Here they are, on the refinement cycles 1 and 4, +clearly showing that the solution is indeed composed of discontinuous piecewise +polynomials:
- + - +
- + - +
@@ -127,22 +188,27 @@ algorithms (right). We see, that the solution on the anisotropically refined mesh is very similar to the solution obtained on the isotropically refined mesh. Thus the anisotropic indicator seems to effectively select the appropriate cells for anisotropic -refinement. This observation is strengthened by the plot of the an adapted -anisotropic grid, e.g. the grid after three refinement steps. - - +refinement. +The pictures also explain why the mesh is refined as it is. In the whole left part of the domain refinement is only performed along the -y-axis of cells. In the right part of the domain the refinement is dominated by +$y$-axis of cells. In the right part of the domain the refinement is dominated by isotropic refinement, as the anisotropic feature of the solution - the jump from -one to zero - is not well aligned with the mesh. However, at the bottom and -leftmost parts of the quarter circle this jumps becomes more and more aligned +one to zero - is not well aligned with the mesh where the advection direction +takes a turn. However, at the bottom and closest (to the observer) parts of the +quarter circle this jumps again becomes more and more aligned with the mesh and the refinement algorithm reacts by creating anisotropic cells of increasing aspect ratio. It might seem that the necessary alignment of anisotropic features and the coarse mesh can decrease performance significantly for real world -problems. However, that is not always the case. Considering boundary layers in -compressible viscous flows, for example, the mesh is always aligned with the -anisotropic features, thus anisotropic refinement will almost always increase the -efficiency of computations on adapted grids for these cases. +problems. That is not wrong in general: If one were, for example, to apply +anisotropic refinement to problems in which shocks appear (e.g., the +equations solved in step-69), then it many cases the shock is not aligned +with the mesh and anisotropic refinement will help little unless one also +introduces techniques to move the mesh in alignment with the shocks. +On the other hand, many steep features of solutions are due to boundary layers. +In those cases, the mesh is already aligned with the anisotropic features +because it is of course aligned with the boundary itself, and anisotropic +refinement will almost always increase the efficiency of computations on +adapted grids for these cases. diff --git a/examples/step-30/step-30.cc b/examples/step-30/step-30.cc index 6d78192309..9ad0a56f27 100644 --- a/examples/step-30/step-30.cc +++ b/examples/step-30/step-30.cc @@ -901,9 +901,10 @@ namespace Step30 // @sect3{The Rest} // - // The remaining part of the program is again unmodified. Only the creation - // of the original triangulation is changed in order to reproduce the new - // domain. + // The remaining part of the program very much follows the scheme of + // previous tutorial programs. We output the mesh in VTU format (just + // as we did in step-1, for example), and the visualization output + // in VTU format as we almost always do. template void DGMethod::output_results(const unsigned int cycle) const { @@ -913,42 +914,31 @@ namespace Step30 else refine_type = ".iso"; - std::string filename = "grid-"; - filename += ('0' + cycle); - Assert(cycle < 10, ExcInternalError()); - - filename += refine_type + ".eps"; - std::cout << "Writing grid to <" << filename << ">..." << std::endl; - std::ofstream eps_output(filename); - - GridOut grid_out; - grid_out.write_eps(triangulation, eps_output); - - filename = "grid-"; - filename += ('0' + cycle); - Assert(cycle < 10, ExcInternalError()); - - filename += refine_type + ".gnuplot"; - std::cout << "Writing grid to <" << filename << ">..." << std::endl; - std::ofstream gnuplot_grid_output(filename); - - grid_out.write_gnuplot(triangulation, gnuplot_grid_output); + { + const std::string filename = + "grid-" + std::to_string(cycle) + refine_type + ".svg"; + std::cout << " Writing grid to <" << filename << ">..." << std::endl; + std::ofstream svg_output(filename); - filename = "sol-"; - filename += ('0' + cycle); - Assert(cycle < 10, ExcInternalError()); + GridOut grid_out; + grid_out.write_svg(triangulation, svg_output); + } - filename += refine_type + ".gnuplot"; - std::cout << "Writing solution to <" << filename << ">..." << std::endl; - std::ofstream gnuplot_output(filename); + { + const std::string filename = + "sol-" + std::to_string(cycle) + refine_type + ".vtu"; + std::cout << " Writing solution to <" << filename << ">..." + << std::endl; + std::ofstream gnuplot_output(filename); - DataOut data_out; - data_out.attach_dof_handler(dof_handler); - data_out.add_data_vector(solution2, "u"); + DataOut data_out; + data_out.attach_dof_handler(dof_handler); + data_out.add_data_vector(solution2, "u"); - data_out.build_patches(degree); + data_out.build_patches(degree); - data_out.write_gnuplot(gnuplot_output); + data_out.write_vtu(gnuplot_output); + } } @@ -993,11 +983,13 @@ namespace Step30 Timer assemble_timer; assemble_system(); - std::cout << "Time of assemble_system: " << assemble_timer.cpu_time() + std::cout << " Time of assemble_system: " << assemble_timer.cpu_time() << std::endl; solve(solution2); output_results(cycle); + + std::cout << std::endl; } } } // namespace Step30 -- 2.39.5