Coverage for /usr/share/miniconda3/envs/dolfin/lib/python3.8/site-packages/block/iterative/tfqmr.py: 4%

70 statements  

« prev     ^ index     » next       coverage.py v7.2.1, created at 2023-03-20 13:03 +0000

1from __future__ import division 

2from .common import * 

3 

4def tfqmr(B, A, x, b, tolerance, maxiter, progress, relativeconv=False, callback=None): 

5 ##### 

6 # Adapted from PyKrylov (https://github.com/dpo/pykrylov; LGPL license) 

7 ##### 

8 

9 r0 = b - A*x 

10 

11 rho = inner(r0,r0) 

12 alphas = [] 

13 betas = [] 

14 residuals = [sqrt(rho)] 

15 

16 if relativeconv: 

17 tolerance *= residuals[0] 

18 

19 if residuals[-1] < tolerance: 

20 return x, residuals, [], [] 

21 

22 y = r0.copy() # Initial residual vector 

23 w = r0.copy() 

24 d = 0*b 

25 theta = 0.0 

26 eta = 0.0 

27 k = 0 

28 

29 z = B*y 

30 u = A*z 

31 v = u.copy() 

32 

33 while k < maxiter: 

34 

35 k += 1 

36 progress += 1 

37 sigma = inner(r0,v) 

38 alpha = rho/sigma 

39 

40 # First pass 

41 w -= alpha * u 

42 d *= theta * theta * eta / alpha 

43 d += z 

44 

45 residNorm = residuals[-1] 

46 theta = norm(w)/residNorm 

47 c = 1.0/sqrt(1 + theta*theta) 

48 residNorm *= theta * c 

49 eta = c * c * alpha 

50 x += eta * d 

51 m = 2.0 * k - 1.0 

52 if residNorm * sqrt(m+1) < tolerance: 

53 break 

54 

55 # Second pass 

56 m += 1 

57 y -= alpha * v 

58 z = B*y 

59 

60 u = A*z 

61 w -= alpha * u 

62 d *= theta * theta * eta / alpha 

63 d += z 

64 theta = norm(w)/residNorm 

65 c = 1.0/sqrt(1 + theta*theta) 

66 residNorm *= theta * c 

67 eta = c * c * alpha 

68 x += eta * d 

69 

70 residual = residNorm * sqrt(m+1) 

71 

72 # Call user provided callback with solution 

73 if callable(callback): 

74 callback(k=k, x=x, r=residual) 

75 

76 residuals.append(residual) 

77 if residual < tolerance or k >= maxiter: 

78 break 

79 

80 # Final updates 

81 rho_next = inner(r0,w) 

82 beta = rho_next/rho 

83 rho = rho_next 

84 

85 alphas.append(alpha) 

86 betas.append(beta) 

87 

88 # Update y 

89 y *= beta 

90 y += w 

91 

92 # Partial update of v with current u 

93 v *= beta 

94 v += u 

95 v *= beta 

96 

97 # Update u 

98 z = B*y 

99 u = A*z 

100 

101 # Complete update of v 

102 v += u 

103 

104 return x, residuals, alphas, betas