What block preconditioners really do

More
4 years 6 months ago #2676 by jan@papez.org
Hello,

I wonder what block preconditioners build using
Code:
CreateBlockSmoother
really do.

In my code, I want to use block Jacobi smoother and I observed that
Code:
rho.data = smoother * b rho.data *= weight
gives different results than
Code:
b *= weight rho.data = smoother * b

Do I miss something? I use quite particular construction of blocks for block smoother (I consider the dofs corresponding to each patch but those on the boundary.). Nevertheless, I would not expect such behavior for any block smoother.

Many thanks for any help,
Jan Papez
More
4 years 6 months ago - 4 years 6 months ago #2677 by lkogler
BlockSmoother used with the matrix-vector multiplication is Block-Jacobi, so linear.

BlockSmoother used multiplicatively is Block-Gauss-Seidel.

If rho is 0,
Code:
smoother.Smooth(rho, b)
and also the symmtric version
Code:
smoother.Smooth(rho, b) smoother.SmoothBack(rho, b)
are linear operations.


Best,
Lukas
Last edit: 4 years 6 months ago by lkogler.
More
4 years 6 months ago #2678 by jan@papez.org
Thank you , Lukas. This is exactly what I learnt from the tutorials. However, then I would expect to have the same results (for the codes given in my initial post), which is not the case.
More
4 years 6 months ago #2679 by lkogler
You should get the same result.

Could you upload a failing minimal example?
More
4 years 6 months ago - 4 years 6 months ago #2682 by jan@papez.org
I enclose an example, which is not very minimal but provides different results for two variants (switch on the line 8 ) of computations on lines 101-106.

( I use a multigrid solver with adaptive stepsize computed on lines 157-160. )

Many thanks for your help!
Jan

File Attachment:

File Name: minimal_example.py
File Size:5 KB
Last edit: 4 years 6 months ago by jan@papez.org.
More
4 years 6 months ago - 4 years 6 months ago #2683 by lkogler
In variant 2 you modify b, which you seem to use again at another point:
Code:
if variant == 1: rho.data = self.smoothers[level] * b rho.data *= (1./self.w1) #weightening else: b.data *= (1./self.w1) rho.data = self.smoothers[level] * b

Changing this to:
Code:
if variant == 1: rho.data = self.smoothers[level] * b rho.data *= (1./self.w1) #weightening else: b.data *= (1./self.w1) rho.data = self.smoothers[level] * b b.data *= self.w1
solves the problem.


Another thing: It seems that you are only using blocks consisting of one DOF each. Using ".CreateSmoother()" instead of ".CreateBlockSmoother()" might be cheaper.
Last edit: 4 years 6 months ago by lkogler.
The following user(s) said Thank You: jan@papez.org
Time to create page: 0.119 seconds