Coverage for /usr/share/miniconda3/envs/dolfin/lib/python3.8/site-packages/block/iterative/conjgrad.py: 75%
45 statements
« prev ^ index » next coverage.py v7.2.1, created at 2023-03-20 13:03 +0000
« prev ^ index » next coverage.py v7.2.1, created at 2023-03-20 13:03 +0000
1from __future__ import division
2from __future__ import print_function
3from .common import *
5def precondconjgrad(B, A, x, b, tolerance, maxiter, progress, relativeconv=False, robustresidual=False, callback=None):
6 #####
7 # Adapted from code supplied by KAM (Simula PyCC; GPL license). This code
8 # relicensed under LGPL v2.1 or later, in agreement with the original
9 # authors:
10 # Kent Andre Mardal <kent-and@simula.no>
11 # Ola Skavhaug <skavhaug@simula.no>
12 # Gunnar Staff <gunnaran@simula.no>
13 #####
15 r = b - A*x
16 z = B*r
17 d = z
18 rz = inner(r,z)
19 if rz < 0: 19 ↛ 20line 19 didn't jump to line 20, because the condition on line 19 was never true
20 raise ValueError('Preconditioner not positive-definite')
22 iter = 0
23 alphas = []
24 betas = []
25 residuals = [sqrt(rz)]
27 if relativeconv: 27 ↛ 28line 27 didn't jump to line 28, because the condition on line 27 was never true
28 tolerance *= residuals[0]
30 while residuals[-1] > tolerance and iter < maxiter:
31 z = A*d
32 dz = inner(d,z)
33 if dz == 0: 33 ↛ 34line 33 didn't jump to line 34, because the condition on line 33 was never true
34 print(f'ConjGrad breakdown')
35 break
36 alpha = rz/dz
37 x += alpha*d
38 if robustresidual: 38 ↛ 39line 38 didn't jump to line 39, because the condition on line 38 was never true
39 r = b - A*x
40 else:
41 r -= alpha*z
42 z = B*r
43 rz_prev = rz
44 rz = inner(r,z)
45 if rz < 0: 45 ↛ 46line 45 didn't jump to line 46, because the condition on line 45 was never true
46 print (f'Preconditioner not positive-definite')
47 # Restore pre-breakdown state. Don't know if it helps any, but it's
48 # consistent with returned quasi-residuals.
49 x -= alpha*d
50 break
51 beta = rz/rz_prev
52 d = z + beta*d
54 residual = sqrt(rz)
56 # Call user provided callback with solution
57 if callable(callback): 57 ↛ 58line 57 didn't jump to line 58, because the condition on line 57 was never true
58 callback(k=iter, x=x, r=residual)
60 iter += 1
61 progress += 1
62 alphas.append(alpha)
63 betas.append(beta)
64 residuals.append(residual)
66 return x, residuals, alphas, betas