New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revise iteration in PreconditionChebyshev #7703
Conversation
/rebuild |
*/ | ||
void | ||
do_transpose_chebyshev_loop(VectorType &dst, const VectorType &src) const; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For someone reviewing this part: We had previously put the code for vmult()
and step()
as well as Tvmult()
and Tstep()
into these common functions. Given some changes, I would now also have to pass the iteration index. Given that each function only calls two other functions and does an update to a scalar, I have put the code inline because it does not save us any lines in the end.
Probably somehow relevant: in a parallel setting, the initial vector is set to something like 1/norm with 0-th entry explicitly 0. |
@tcclevenger FYI. |
This is something that has bothered me for a while indeed. For deal.II's own vectors, we set something like My advise would be to to pull out the eigenvalue computation to user code. To use this, you should set |
One thing we tried to do in the past is to use the right hand side that is given the first time |
c16245f
to
9b51ace
Compare
@kronbichler Please rebase and resolve the merge conflict :-) |
9b51ace
to
e82b695
Compare
@kronbichler , what is this diagonal_matrix.h.2 file thing about? |
e82b695
to
b3dc62d
Compare
Sorry, left over from some experiments. I removed it. |
include/deal.II/lac/precondition.h
Outdated
solution.swap(temp_vector1); | ||
solution_old.swap(temp_vector1); | ||
} | ||
else if (iteration_index > 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iteration_index is always positive, which makes this logic somewhat weird (as this check is unnecessary). Is there a reason you don't start with iteration=0
? (here and above of course)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait: that is not true, you also call it with 0. Does it make sense to make an empty
if (iteration_index==0)
{
// nothing to do here, because ....
}
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it would make sense to add this part to make it similar to the other if statements cases.
@@ -342,7 +342,7 @@ do_test(const DoFHandler<dim> &dof) | |||
++level) | |||
{ | |||
smoother_data[level].smoothing_range = 15.; | |||
smoother_data[level].degree = 5; | |||
smoother_data[level].degree = 6; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test change does not change the output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is necessary after #7708 with the change in what the Chebyshev degree means. That PR was open while the test, added in #7696, was also open. So this simply fixes an only remotely related issue, see also here:
https://cdash.kyomu.43-1.org/viewTest.php?onlydelta&buildid=7762
90901ac
to
8bb4172
Compare
/rebuild |
8bb4172
to
4845efd
Compare
4845efd
to
75eec85
Compare
I rebased to re-start the testers that were failing spuriously on a |
@@ -976,7 +1018,7 @@ class PreconditionChebyshev : public Subscriptor | |||
/** | |||
* Constructor. | |||
*/ | |||
AdditionalData(const unsigned int degree = 0, | |||
AdditionalData(const unsigned int degree = 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a follow-up change to #7708, isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I had forgotten that change there and one of the exceptions I introduced here revealed this issue in a test.
The old implementation of
PreconditionChebyshev
used an iteration that was more complicated than necessary due to a temporary vector representingx^{n-1}-x^{n}
. I have rewritten the algorithm directly in terms of the underlying three-term recurrencex^{n+1} = x^{n} + f1 (x^{n}-x^{n-1}) + f2 P^{-1} (b-A x^{n})
wheref1
andf2
are some factors. This has the advantage of being slightly faster because we do not need to update the temporary vector and only load fromx^{n-1}
instead, i.e., we save one vector write, reducing the access in the vector updates from five reads and two writes to five reads (x^n, x^{n-1}, P^{-1}, t=Ax^n, b
) and one write tox
. Overall, it depends on the cost of the matrix-vector product how much this reduction by around 15% helps in final cost. I measured up to 5% of the solution with a multigrid algorithm, which is not bad.Furthermore, the new implementation should be more comprehensible to someone familiar with Chebyshev polynomials. I adapted the variable names for the temporary vectors to make things clearer and have also stated the recurrence relation in the class description.
Since the algorithm should be mathematically equivalent to the one we had before, we should not need any test changes (checked on my machine).