From 5767f2d4d3d2bcaed45d7988e5468fe834f7fb02 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Mon, 8 Jan 2018 01:08:06 -0700 Subject: [PATCH] Minor edits to the positivity-preserving section of step-25 --- examples/step-26/doc/results.dox | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/examples/step-26/doc/results.dox b/examples/step-26/doc/results.dox index da1c4dccc8..23790cc711 100644 --- a/examples/step-26/doc/results.dox +++ b/examples/step-26/doc/results.dox @@ -140,7 +140,9 @@ The general form of the $i$th equation then reads: a_{ii} u^{n}_i &= b_{ii} u^{n-1}_i + \sum\limits_{j \in S_i} \left( b_{ij} u^{n-1}_j - a_{ij} u^{n}_j \right), @f} -where $S_i$ is the set of nearest neighbors to node $i$. If all coefficients +where $S_i$ is the set of degrees of freedom that DoF $i$ couples with (i.e., +for which either the matrix $A$ or matrix $B$ has a nonzero entry at position +$(i,j)$). If all coefficients fulfill the following conditions: @f{align*} a_{ii} &> 0, & b_{ii} &\leq 0, & a_{ij} &\leq 0, & b_{ij} &\geq 0, @@ -158,9 +160,9 @@ the Crank-Nicolson scheme, Schatz et. al. have translated it to the following ones: @f{align*} - (1 - \theta) k a_{ii} &\leq m_{ii},~ \forall i, + (1 - \theta) k a_{ii} &\leq m_{ii},\qquad \forall i, & - \theta k \left| a_{ij} \right| &\geq m_{ij},~ j \neq i, + \theta k \left| a_{ij} \right| &\geq m_{ij},\qquad j \neq i, @f} where $M = m_{ij}$ denotes the mass matrix and $A = a_{ij}$ the stiffness matrix with $a_{ij} \leq 0$ for $j \neq i$, respectively. With @@ -173,30 +175,34 @@ follows: k_{\text{min}} &= \frac{ 1 }{ \theta } \max\left( \frac{ m_{ij} }{ \left|a_{ij}\right| } \right),~ j \neq i. @f} - -Here, it is worth mentioning that the time step is constrained by both a lower -and upper bound in case of a Crank-Nicolson scheme. These bounds should be +In other words, the time step is constrained by both a lower +and upper bound in case of a Crank-Nicolson scheme. These bounds should be considered along with the CFL condition to ensure significance of the performed simulations. -To ensure positivity preservation in this particular tutorial, we can use +Being unable to make the time step as small as we want to get more +accuracy without losing the positivity property is annoying. It raises +the question of whether we can at least compute the minimal time step +we can choose to ensure positivity preservation in this particular tutorial. +Indeed, we can use the SparseMatrix objects for both mass and stiffness that are created via the MatrixCreator functions. Iterating through each entry via SparseMatrixIterators lets us check for diagonal and off-diagonal entries to set a proper time step dynamically. For quadratic matrices, the diagonal element is stored as the -first member of a row (see SparseMatrix documentation). A exemplary code +first member of a row (see SparseMatrix documentation). An exemplary code snippet on how to grab the entries of interest from the mass_matrix is shown below. @code Assert (mass_matrix.m() == mass_matrix.n(), ExcNotQuadratic()); -const unsigned int& num_rows = mass_matrix.m(); -double mass_matrix_min_diag = 1e100, +const unsigned int num_rows = mass_matrix.m(); +double mass_matrix_min_diag = std::numeric_limits::max(), mass_matrix_max_offdiag = 0.; SparseMatrixIterators::Iterator row_it (&mass_matrix, 0); -for(unsigned int m = 0; mvalue(), mass_matrix_min_diag); @@ -207,3 +213,6 @@ for(unsigned int m = 0; mvalue(), mass_matrix_max_offdiag); } @endcode + +Using the information so computed, we can bound the time step via the formulas +above. -- 2.39.5