]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Slight update in comments of step-22. Mention the changes on the news page.
authorkronbichler <kronbichler@0785d39b-7218-0410-832d-ea1e28bc413d>
Mon, 20 Apr 2009 12:41:04 +0000 (12:41 +0000)
committerkronbichler <kronbichler@0785d39b-7218-0410-832d-ea1e28bc413d>
Mon, 20 Apr 2009 12:41:04 +0000 (12:41 +0000)
git-svn-id: https://svn.dealii.org/trunk@18655 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/doc/doxygen/tutorial/toc.html
deal.II/doc/news/changes.h
deal.II/examples/step-22/doc/intro.dox
deal.II/examples/step-22/doc/results.dox
deal.II/examples/step-22/doc/step-22.3d.mesh-6.png [deleted file]
deal.II/examples/step-22/step-22.cc

index e7c70e15b967f241d25187884d0a2623c2dad6fc..15d838d7df73fb3c22f375d95fad5bee2039bc5b 100644 (file)
@@ -210,13 +210,13 @@ searching for programs with a certain functionality.
   <tr valign="top">
       <td><a href="../../doxygen/deal.II/step_22.html">Step-22</a></td>
       <td> Solving the Stokes equations of slow fluid flow on adaptive
-      meshes. More on Schur complement solvers
+      meshes. More on Schur complement solvers. Advanced use of the
+      ConstraintMatrix class.
       </td></tr>
 
   <tr valign="top">
       <td><a href="../../doxygen/deal.II/step_23.html">Step-23</a></td>
-      <td> Finally a "real" time dependent problem,
-      the wave equation.
+      <td> Finally a "real" time dependent problem, the wave equation.
       </td></tr>
 
   <tr valign="top">
index 0a6ac0c629992df741fe7c36f7f0aae06a41eace..d9ac8f816e88538bf36a55191244e53e01f3c2db 100644 (file)
@@ -158,6 +158,17 @@ inconvenience this causes.
 <h3>General</h3>
 
 <ol>
+  <li>
+  <p>
+  Updated: The @ref step_22 "step-22" tutorial program now uses some 
+  advanced features of the ConstraintMatrix such as imhomogeneities 
+  for implementing Dirichlet boundary condition and condensation of 
+  constraints on the fly.
+  <br>
+  (Martin Kronbichler 2009/04/20)
+  </p>
+  </li>
+
   <li>
   <p>
   New: There is now a program, contributed by Jean-Paul Pelteret, that can
@@ -224,7 +235,7 @@ inconvenience this causes.
   (WB 2009/01/12)
   </p>
   </li>
-  
+
   <li>
   <p>
   Updated: The @ref step_33 "step-33" tutorial program now uses the
index e14b0f4990a6d2cfcd9d13c2f099adf24635de95..2c3ea9d30248e616c1a4c96f93ba11e721b7802d 100644 (file)
@@ -602,7 +602,9 @@ surface that sucks material all the way to the top surface to fill the gap
 left by the outward motion of material at this location.
 
 
-<h3>Using imhomogeneous constraints for implementing Dirichlet boundary conditions</h3>
+<h3>Implementation</h3>
+
+<h4>Using imhomogeneous constraints for implementing Dirichlet boundary conditions</h4>
 
 In all the previous tutorial programs, we used the ConstraintMatrix merely
 for handling hanging node constraints (with exception of step-11). However,
@@ -650,13 +652,13 @@ side, it distributes the hanging node constraints and additionally
 implements (inhomogeneous) Dirichlet boundary conditions. That's nice, isn't
 it?
 
-As results from this discussion, we can conclude that the ConstraintMatrix
-provides an alternative to using MatrixTools::apply_boundary_values for
-implementing Dirichlet boundary conditions.
+We can conclude that the ConstraintMatrix provides an alternative to using
+MatrixTools::apply_boundary_values for implementing Dirichlet boundary
+conditions.
 
 
 <a name="constraint-matrix">
-Other ConstraintMatrix-related optimizations
+<h4>Using ConstraintMatrix for performance optimizations</h4>
 </a>
 
 Usually, the sparse matrix contains a substantial amount of elements that
@@ -670,54 +672,56 @@ considered in this tutorial program. Remember that matrix-vector products or
 preconditioners operate on all these elements that are zero, which is an
 inefficiency we have chosen to eliminate in the tutorial program.
 
-Another advantage of directly resolving constrained degrees of freedom is
-that we can avoid having all these entries that actually are zero in our
-sparse matrix &mdash; we do not need them during matrix construction (as
-opposed to the traditional algorithms, which first fill the matrix, and only
-resolve constraints afterwards). The way we are going to do that is to pass
-the information about constraints to the function that generates the
-sparsity pattern, and then set a <tt>false</tt> argument specifying that we
-do not intend to use constrained entries:
+An advantage of directly resolving constrained degrees of freedom is that we
+can avoid having all these entries that actually are zero in our sparse
+matrix &mdash; we do not need them during matrix construction (as opposed to
+the traditional algorithms, which first fill the matrix, and only resolve
+constraints afterwards). This will save both memory and time when forming
+matrix-vector products. The way we are going to do that is to pass the
+information about constraints to the function that generates the sparsity
+pattern, and then set a <tt>false</tt> argument specifying that we do not
+intend to use constrained entries:
 @code
   DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern,
                                    constraints, false);
 @endcode
-This functions saves, by the way, also the call to the <tt>condense()</tt>
-function on the sparsity pattern.
+This functions obviates, by the way, also the call to the
+<tt>condense()</tt> function on the sparsity pattern.
 
 
-<h3>Implementation</h3>
+<h4>Performance optimizations</h4>
 
-The program developed below has seen a lot of TLC. We have run it over
-and over under profiling tools (mainly <a
-href="http://www.valgrind.org/">valgrind</a>'s cachegrind and
-callgrind tools, as well as the KDE <a
+The program developed below has seen a lot of TLC. We have run it over and
+over under profiling tools (mainly <a
+href="http://www.valgrind.org/">valgrind</a>'s cachegrind and callgrind
+tools, as well as the KDE <a
 href="http://kcachegrind.sourceforge.net/">KCachegrind</a> program for
-visualization) to see where the bottlenecks are. This has paid off:
-through this effort, the program has become almost twice as fast when
+visualization) to see where the bottlenecks are. This has paid off: through
+this effort, the program has become about four times as fast when
 considering the runtime of the refinement cycles zero through three,
 reducing the overall number of CPU instructions executed from
-869,574,060,348 to 199,853,005,625. For higher refinement levels, the
-gain is probably even larger since some algorithms that are not ${\cal
-O}(N)$ have been eliminated.
-
-Essentially, there are currently two algorithms in the program that do
-not scale linearly with the number of degrees of freedom: renumbering
-of degrees of freedom, and the linear solver. As for the first, while
-reordering degrees of freedom may not scale linearly, it is an
-indispensible part of the overall algorithm as it greatly improves the
-quality of the sparse ILU, easily making up for the time spent on
-computing the renumbering; graphs and timings to demonstrate this are
-shown in the documentation of the DoFRenumbering namespace, also
-underlining the choice of the King reordering algorithm chosen below.
-
-As for the linear solver: as mentioned above, our implementation here
-uses a Schur complement formulation. This is not necessarily the very
-best choice but demonstrates various important techniques available in
-deal.II. The question of which solver is best is again discussed in
-the <a href="#improved-solver">section on improved solvers in the
-results part</a> of this program, along with code showing alternative
-solvers and a comparison of their results.
+869,574,060,348 to 199,853,005,625. For higher refinement levels, the gain
+is probably even larger since some algorithms that are not ${\cal O}(N)$
+have been eliminated.
+
+Essentially, there are currently two algorithms in the program that do not
+scale linearly with the number of degrees of freedom: renumbering of degrees
+of freedom (which is ${\val O}(N \log N)$, and the linear solver (which is
+{\val O}(N^{4/3})$). As for the first, while reordering degrees of freedom
+may not scale linearly, it is an indispensible part of the overall algorithm
+as it greatly improves the quality of the sparse ILU, easily making up for
+the time spent on computing the renumbering; graphs and timings to
+demonstrate this are shown in the documentation of the DoFRenumbering
+namespace, also underlining the choice of the King reordering algorithm
+chosen below.
+
+As for the linear solver: as mentioned above, our implementation here uses a
+Schur complement formulation. This is not necessarily the very best choice
+but demonstrates various important techniques available in deal.II. The
+question of which solver is best is again discussed in the <a
+href="#improved-solver">section on improved solvers in the results part</a>
+of this program, along with code showing alternative solvers and a
+comparison of their results.
 
 Apart from this, many other algorithms have been tested and improved during
 the creation of this program. For example, in building the sparsity pattern,
@@ -727,14 +731,15 @@ large numbers of nonzero entries per row created by our discretization in
 3d, leading to a quadratic behavior. Replacing the internal algorithms in
 deal.II to set many elements at a time, and using a
 BlockCompressedSimpleSparsityPattern as a better adapted data structure,
-removed this bottleneck at the price of some more memory
+removed this bottleneck at the price of a slightly higher memory
 consumption. Likewise, the implementation of the decomposition step in the
 SparseILU class was very inefficient and has been replaced by one that is
-about 10 times faster. Small improvements were applied here and
-there. Moreover, the ConstraintMatrix object has been used to eliminate a
-lot of entries in the sparse matrix that are eventually going to be zero,
-see <a href="#constraint-matrix">the section on new features of
-constraint matrix</a>.
+about 10 times faster. Even the vmult function of the SparseILU has been
+improved to save about twenty precent of time. Small improvements were
+applied here and there. Moreover, the ConstraintMatrix object has been used
+to eliminate a lot of entries in the sparse matrix that are eventually going
+to be zero, see <a href="#constraint-matrix">the section on using advanced
+features of the ConstraintMatrix class</a>.
 
 A profile of how many CPU instructions are spent at the various
 different places in the program during refinement cycles
@@ -744,16 +749,16 @@ zero through three in 3d is shown here:
 
 As can be seen, at this refinement level approximately three quarters of the
 instruction count is spent on the actual solver (the SparseILU::vmult calls
-on the left, the SparseMatrix<double>::vmult call in the middle, and another
-box including multiplications with SparseILU and SparseMatrix stemming from
-the solve for <i>U</i>). About one fifth of the instruction count is spent
-on matrix assembly and sparse ILU computation (box in the lower right
-corner) and the rest on other things. Since floating point operations such
-as in the SparseILU::vmult calls typically take much longer than many of the
-logical operations and table lookups in matrix assembly, the fraction of the
-run time taken up by matrix assembly is actually significantly less than the
-fraction of instructions, as will become apparent in the comparison we make
-in the results section.
+on the left, the SparseMatrix::vmult call in the middle for the Schur
+complement solve, and another box representing the multiplications with
+SparseILU and SparseMatrix in the solve for <i>U</i>). About one fifth of
+the instruction count is spent on matrix assembly and sparse ILU computation
+(box in the lower right corner) and the rest on other things. Since floating
+point operations such as in the SparseILU::vmult calls typically take much
+longer than many of the logical operations and table lookups in matrix
+assembly, the fraction of the run time taken up by matrix assembly is
+actually significantly less than the fraction of instructions, as will
+become apparent in the comparison we make in the results section.
 
 For higher refinement levels, the boxes representing the solver as well as
 the blue box at the top right stemming from reordering algorithm are going
index 3599cda871285342d243b53dc315a1debf2ee9c8..00a5e21fc6d0ce34c5a2ee74e07660134e962d3a 100644 (file)
@@ -175,7 +175,7 @@ Refinement cycle 5
 Again, we see that the number of outer iterations does not increase as
 we refine the mesh. Nevertheless, the compute time increases
 significantly: for each of the iterations above separately, it takes a
-few seconds, a few seconds, 1min, 5min, 21min, and 1h35. This overall
+few seconds, a few seconds, 30sec, 4min, 15min, and 1h18min. This overall
 superlinear (in the number of unknowns) increase in runtime is due to the fact
 that our inner solver is not ${\cal O}(N)$: a simple experiment shows
 that as we keep refining the mesh, the average number of
@@ -218,15 +218,6 @@ look as follow:
       @image html step-22.3d.mesh-5.png
     </td>
   </tr>
-
-  <tr>
-    <td ALIGN="center">
-      @image html step-22.3d.mesh-6.png
-    </td>
-
-    <td ALIGN="center">
-    </td>
-  </tr>
 </table>
 
 Again, they show essentially the location of singularities introduced
@@ -603,158 +594,147 @@ Let's first see the results in 2D:
 @code
 Refinement cycle 0
    Number of active cells: 64
-   Number of degrees of freedom: 679 (594+85) [0.013998 s] 
-   Assembling... [0.004999 s]
-   Computing preconditioner... [0.003999 s]
+   Number of degrees of freedom: 679 (594+85) [0.005999 s] 
+   Assembling... [0.002 s]
+   Computing preconditioner... [0.003 s]
    Solving...
-      Schur complement:   11 outer CG iterations for p  [0.010999 s]
-      Block Schur preconditioner:   11 GMRES iterations [0.009998 s]
-   difference l_infty between solution vectors: 3.18714e-06
+      Schur complement:  11 outer CG iterations for p  [0.007999 s]
+      Block Schur preconditioner:  12 GMRES iterations [0.008998 s]
+   difference l_infty between solution vectors: 8.18909e-07
 
 Refinement cycle 1
    Number of active cells: 160
-   Number of degrees of freedom: 1683 (1482+201) [0.040994 s] 
-   Assembling... [0.013998 s]
-   Computing preconditioner... [0.016997 s]
+   Number of degrees of freedom: 1683 (1482+201) [0.013998 s] 
+   Assembling... [0.005999 s]
+   Computing preconditioner... [0.012998 s]
    Solving...
-      Schur complement:   11 outer CG iterations for p  [0.033995 s]
-      Block Schur preconditioner:   12 GMRES iterations [0.035995 s]
-   difference l_infty between solution vectors: 9.32671e-06
+      Schur complement:  11 outer CG iterations for p  [0.029995 s]
+      Block Schur preconditioner:  12 GMRES iterations [0.030995 s]
+   difference l_infty between solution vectors: 9.32504e-06
 
 Refinement cycle 2
    Number of active cells: 376
-   Number of degrees of freedom: 3813 (3370+443) [0.099985 s] 
-   Assembling... [0.033995 s]
-   Computing preconditioner... [0.052992 s]
+   Number of degrees of freedom: 3813 (3370+443) [0.031995 s] 
+   Assembling... [0.014998 s]
+   Computing preconditioner... [0.044994 s]
    Solving...
-      Schur complement:   11 outer CG iterations for p  [0.110983 s]
-      Block Schur preconditioner:   12 GMRES iterations [0.110983 s]
-   difference l_infty between solution vectors: 4.26989e-06
+      Schur complement:  11 outer CG iterations for p  [0.079987 s]
+      Block Schur preconditioner:  13 GMRES iterations [0.092986 s]
+   difference l_infty between solution vectors: 5.40689e-06
 
 Refinement cycle 3
    Number of active cells: 880
-   Number of degrees of freedom: 8723 (7722+1001) [0.238963 s] 
-   Assembling... [0.076989 s]
-   Computing preconditioner... [0.141978 s]
+   Number of degrees of freedom: 8723 (7722+1001) [0.074988 s] 
+   Assembling... [0.035995 s]
+   Computing preconditioner... [0.110983 s]
    Solving...
-      Schur complement:   11 outer CG iterations for p  [0.289956 s]
-      Block Schur preconditioner:   12 GMRES iterations [0.304953 s]
-   difference l_infty between solution vectors: 1.0266e-05
+      Schur complement:  11 outer CG iterations for p  [0.19697 s]
+      Block Schur preconditioner:  13 GMRES iterations [0.242963 s]
+   difference l_infty between solution vectors: 1.14676e-05
 
 Refinement cycle 4
    Number of active cells: 2008
-   Number of degrees of freedom: 19383 (17186+2197) [0.561914 s] 
-   Assembling... [0.170974 s]
-   Computing preconditioner... [0.409938 s]
+   Number of degrees of freedom: 19383 (17186+2197) [0.180973 s] 
+   Assembling... [0.081987 s]
+   Computing preconditioner... [0.315952 s]
    Solving...
-      Schur complement:   11 outer CG iterations for p  [0.740887 s]
-      Block Schur preconditioner:   13 GMRES iterations [0.837873 s]
-   difference l_infty between solution vectors: 3.13139e-05
+      Schur complement:  11 outer CG iterations for p  [0.673898 s]
+      Block Schur preconditioner:  13 GMRES iterations [0.778882 s]
+   difference l_infty between solution vectors: 3.13142e-05
 
 Refinement cycle 5
    Number of active cells: 4288
-   Number of degrees of freedom: 40855 (36250+4605) [1.25581 s] 
-   Assembling... [0.353946 s]
-   Computing preconditioner... [1.21681 s]
+   Number of degrees of freedom: 40855 (36250+4605) [0.386941 s] 
+   Assembling... [0.171974 s]
+   Computing preconditioner... [0.766883 s]
    Solving...
-      Schur complement:   11 outer CG iterations for p  [1.60576 s]
-      Block Schur preconditioner:   13 GMRES iterations [1.84572 s]
-   difference l_infty between solution vectors: 8.59663e-05
-
-Refinement cycle 6
-   Number of active cells: 8896
-   Number of degrees of freedom: 83885 (74474+9411) [2.54961 s] 
-   Assembling... [0.732889 s]
-   Computing preconditioner... [3.9704 s]
-   Solving...
-      Schur complement:   11 outer CG iterations for p  [3.70344 s]
-      Block Schur preconditioner:   13 GMRES iterations [4.18436 s]
-   difference l_infty between solution vectors: 0.00022514
+      Schur complement:  11 outer CG iterations for p  [1.65275 s]
+      Block Schur preconditioner:  13 GMRES iterations [1.81372 s]
+   difference l_infty between solution vectors: 8.59668e-05
 @endcode
 
-We see that there is no huge difference in the solution time between
-the block Schur complement preconditioner solver and the Schur 
-complement itself. The
-reason is simple: we used a direct solve as preconditioner for $A$ - so
-there is no substantial gain by avoiding the inner iterations. We see
-that the number of iterations has slightly increased for GMRES, but all in all
-the two choices are fairly similar.
+We see that there is no huge difference in the solution time between the
+block Schur complement preconditioner solver and the Schur complement
+itself. The reason is simple: we used a direct solve as preconditioner for
+$A$ - so we cannot expect any gain by avoiding the inner iterations. We see
+that the number of iterations has slightly increased for GMRES, but all in
+all the two choices are fairly similar.
 
 The picture of course changes in 3D:
 
 @code
 Refinement cycle 0
    Number of active cells: 32
-   Number of degrees of freedom: 1356 (1275+81) [0.336021 s] 
-   Assembling... [0.204013 s]
-   Computing preconditioner... [0.128008 s]
+   Number of degrees of freedom: 1356 (1275+81) [0.025996 s] 
+   Assembling... [0.056992 s]
+   Computing preconditioner... [0.027995 s]
    Solving...
-      Schur complement:   13 outer CG iterations for p  [0.552034 s]
-      Block Schur preconditioner:   23 GMRES iterations [0.072005 s]
-   difference l_infty between solution vectors: 1.11101e-05
+      Schur complement:  13 outer CG iterations for p  [0.275958 s]
+      Block Schur preconditioner:  23 GMRES iterations [0.042994 s]
+   difference l_infty between solution vectors: 1.11307e-05
 
 Refinement cycle 1
    Number of active cells: 144
-   Number of degrees of freedom: 5088 (4827+261) [0.79605 s] 
-   Assembling... [0.428026 s]
-   Computing preconditioner... [0.30802 s]
+   Number of degrees of freedom: 5088 (4827+261) [0.102984 s] 
+   Assembling... [0.254961 s]
+   Computing preconditioner... [0.161976 s]
    Solving...
-      Schur complement:   14 outer CG iterations for p  [4.01625 s]
-      Block Schur preconditioner:   41 GMRES iterations [0.632039 s]
-   difference l_infty between solution vectors: 2.36202e-05
+      Schur complement:  14 outer CG iterations for p  [2.43963 s]
+      Block Schur preconditioner:  42 GMRES iterations [0.352946 s]
+   difference l_infty between solution vectors: 9.07409e-06
 
 Refinement cycle 2
    Number of active cells: 704
-   Number of degrees of freedom: 22406 (21351+1055) [4.12826 s] 
-   Assembling... [2.15614 s]
-   Computing preconditioner... [1.6721 s]
+   Number of degrees of freedom: 22406 (21351+1055) [0.52592 s] 
+   Assembling... [1.24481 s]
+   Computing preconditioner... [0.948856 s]
    Solving...
-      Schur complement:   14 outer CG iterations for p  [30.6179 s]
-      Block Schur preconditioner:   75 GMRES iterations [6.01638 s]
-   difference l_infty between solution vectors: 3.86168e-05
+      Schur complement:  14 outer CG iterations for p  [22.2056 s]
+      Block Schur preconditioner:  78 GMRES iterations [4.75928 s]
+   difference l_infty between solution vectors: 2.48042e-05
 
 Refinement cycle 3
    Number of active cells: 3168
-   Number of degrees of freedom: 93176 (89043+4133) [18.8452 s] 
-   Assembling... [9.47659 s]
-   Computing preconditioner... [7.47647 s]
+   Number of degrees of freedom: 93176 (89043+4133) [2.66759 s] 
+   Assembling... [5.66014 s]
+   Computing preconditioner... [4.69529 s]
    Solving...
-      Schur complement:   15 outer CG iterations for p  [228.366 s]
-      Block Schur preconditioner:  159 GMRES iterations [62.6799 s]
-   difference l_infty between solution vectors: 7.34297e-05
+      Schur complement:  15 outer CG iterations for p  [235.74 s]
+      Block Schur preconditioner:  162 GMRES iterations [63.7883 s]
+   difference l_infty between solution vectors: 5.62978e-05
 
 Refinement cycle 4
    Number of active cells: 11456
-   Number of degrees of freedom: 327808 (313659+14149) [77.5688 s] 
-   Assembling... [34.9422 s]
-   Computing preconditioner... [27.9577 s]
+   Number of degrees of freedom: 327808 (313659+14149) [12.0242 s] 
+   Assembling... [20.2669 s]
+   Computing preconditioner... [17.3384 s]
    Solving...
-      Schur complement:   15 outer CG iterations for p  [1040.28 s]
-      Block Schur preconditioner:  292 GMRES iterations [414.738 s]
-   difference l_infty between solution vectors: 0.00019614
+      Schur complement:  15 outer CG iterations for p  [817.287 s]
+      Block Schur preconditioner:  294 GMRES iterations [347.307 s]
+   difference l_infty between solution vectors: 0.000107536
 
 Refinement cycle 5
    Number of active cells: 45056
-   Number of degrees of freedom: 1254464 (1201371+53093) [520.285 s] 
-   Assembling... [136.909 s]
-   Computing preconditioner... [115.455 s]
+   Number of degrees of freedom: 1254464 (1201371+53093) [89.8533 s] 
+   Assembling... [80.3588 s]
+   Computing preconditioner... [73.0849 s]
    Solving...
-      Schur complement:   14 outer CG iterations for p  [6556.39 s]
-      Block Schur preconditioner:  590 GMRES iterations [3906.06 s]
-   difference l_infty between solution vectors: 0.000428885
+      Schur complement:  14 outer CG iterations for p  [4401.66 s]
+      Block Schur preconditioner:  587 GMRES iterations [3083.21 s]
+   difference l_infty between solution vectors: 0.00025531
 @endcode
 
 Here, the block preconditioned solver is clearly superior to the Schur
-complement, but the advantage gets less for more mesh points. This was expected
-from the discussion above. It is also apparent that GMRES scales worse with the 
-problem size than CG (as explained above).
-Nonetheless, the improvement by a factor of 3-5 for moderate problem sizes
-is quite impressive.
-
-<h5>Combining block preconditioner and multigrid</h5>
-An ultimate linear solver for this problem could be imagined as a combination of
-an optimal preconditioner for $A$ (e.g. multigrid) and the block preconditioner
-described above.
+complement, but the advantage gets less for more mesh points. This is
+because GMRES(k) scales worse with the problem size than CG, as we discussed
+above.  Nonetheless, the improvement by a factor of 3-5 for moderate problem
+sizes is quite impressive.
+
+<h5>Combining block preconditioner and multigrid</h5> An ultimate linear
+solver for this problem could be imagined as a combination of an optimal
+preconditioner for $A$ (e.g. multigrid) and the block preconditioner
+described above, which is the approach taken in the @ref step_31 "step-31"
+tutorial program.
 
 <h5>No block matrices and vectors</h5>
 Another possibility that can be taken into account is to not set up a block
diff --git a/deal.II/examples/step-22/doc/step-22.3d.mesh-6.png b/deal.II/examples/step-22/doc/step-22.3d.mesh-6.png
deleted file mode 100644 (file)
index c1d5c55..0000000
Binary files a/deal.II/examples/step-22/doc/step-22.3d.mesh-6.png and /dev/null differ
index 5f7f81b35f99e2ccfb9e40e2085de33df5efff7c..d1092b3ff5e83858cdf845e6c2e83bb64c561d5c 100644 (file)
@@ -934,11 +934,11 @@ void StokesProblem<dim>::assemble_system ()
                                       // the indices in case we are
                                       // pointing into the empty part of
                                       // the local matrix.
-      cell->get_dof_indices (local_dof_indices);
       for (unsigned int i=0; i<dofs_per_cell; ++i)
        for (unsigned int j=i+1; j<dofs_per_cell; ++j)
          local_matrix(i,j) = local_matrix(j,i);
 
+      cell->get_dof_indices (local_dof_indices);
       constraints.distribute_local_to_global (local_matrix, local_rhs,
                                              local_dof_indices, 
                                              system_matrix, system_rhs);

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.