|
1 | 1 | !=====================================================================!
|
2 |
| -! Abstract class for linear solvers to extend and provide iterate |
3 |
| -! method. |
4 |
| -! |
5 |
| -! Author: Komahan Boopathy |
| 2 | +! Interface for linear solvers to implement. |
6 | 3 | !=====================================================================!
|
7 | 4 |
|
8 | 5 | module interface_linear_solver
|
9 | 6 |
|
10 |
| - use iso_fortran_env , only : dp => REAL64 |
11 |
| - use interface_algebraic_solver, only : algebraic_solver |
12 |
| - use interface_assembler , only : assembler |
| 7 | + use iso_fortran_env , only : dp => REAL64 |
13 | 8 |
|
14 | 9 | implicit none
|
15 | 10 |
|
| 11 | + ! Expose only the linear solver interface |
16 | 12 | private
|
17 | 13 | public :: linear_solver
|
18 | 14 |
|
19 | 15 | !===================================================================!
|
20 |
| - ! Abstract linear solver datatype |
| 16 | + ! Linear solver datatype |
21 | 17 | !===================================================================!
|
22 | 18 |
|
23 |
| - type, abstract, extends(algebraic_solver) :: linear_solver |
24 |
| - |
25 |
| - ! Tolerances and print control for iterative solvers |
| 19 | + type, abstract :: linear_solver |
| 20 | + |
26 | 21 | real(dp) :: max_tol
|
27 | 22 | integer :: max_it
|
28 |
| - integer :: print_level |
29 |
| - |
| 23 | + |
30 | 24 | contains
|
31 |
| - |
32 |
| - ! Generic solve procedure |
33 |
| - procedure :: solve |
34 | 25 |
|
35 |
| - ! Iteration behavior is deferred (specific to the type of solver) |
36 |
| - procedure(iterate_interface), deferred :: iterate |
37 |
| - |
| 26 | + ! type bound procedures |
| 27 | + procedure(solve_interface), deferred :: solve |
| 28 | + |
38 | 29 | end type linear_solver
|
39 | 30 |
|
40 | 31 | !===================================================================!
|
41 |
| - ! Interface for deferred iterate function |
| 32 | + ! Interface for multiple constructors |
42 | 33 | !===================================================================!
|
43 | 34 |
|
44 | 35 | interface
|
45 |
| - subroutine iterate_interface(this, system, x) |
| 36 | + subroutine solve_interface(this, x) |
46 | 37 | import linear_solver
|
47 |
| - import assembler |
48 | 38 | import dp
|
49 | 39 | class(linear_solver) , intent(in) :: this
|
50 |
| - class(assembler) , intent(in) :: system |
51 | 40 | real(dp), allocatable , intent(out) :: x(:)
|
52 |
| - end subroutine iterate_interface |
| 41 | + end subroutine solve_interface |
53 | 42 | end interface
|
54 |
| - |
55 |
| -contains |
56 |
| - |
57 |
| - !===================================================================! |
58 |
| - ! Iterative nonlinear solution A x = b(x) |
59 |
| - !===================================================================! |
60 | 43 |
|
61 |
| - subroutine solve(this, system) |
62 |
| - |
63 |
| - class(linear_solver) , intent(in) :: this |
64 |
| - class(assembler) , intent(in) :: system |
65 |
| - |
66 |
| - ! Locals |
67 |
| - real(dp), allocatable :: xold(:), ss(:) |
68 |
| - real(dp) :: update_norm |
69 |
| - integer :: iter, num_inner_iters |
70 |
| - |
71 |
| - ! Initial guess vector for the subspace is "b" |
72 |
| - allocate(x(system % num_state_vars)) |
73 |
| - call system % get_source(x) |
74 |
| - if (norm2(x) .lt. epsilon(1.0_dp)) then |
75 |
| - print *, 'zero rhs? stopping' |
76 |
| - error stop |
77 |
| - end if |
78 |
| - |
79 |
| - allocate(xold(system % num_state_vars)) |
80 |
| - allocate(ss(system % num_state_vars)) |
81 |
| - |
82 |
| - if (this % print_level .eq. -1) then |
83 |
| - open(13, file='sor.res', action='write') |
84 |
| - write(13,*) "iteration ", " residual" |
85 |
| - end if |
86 |
| - |
87 |
| - update_norm = huge(1.0d0); iter = 1; |
88 |
| - outer_iterations: do while (update_norm .gt. this % max_tol) |
89 |
| - |
90 |
| - xold = x |
91 |
| - |
92 |
| - ! Inner iterations with CG (linear solver) |
93 |
| - if ( iter .eq. 1) then |
94 |
| - ss = 0.0d0 |
95 |
| - call this % iterate(system, x, ss, num_inner_iters) |
96 |
| - else |
97 |
| - call system % get_skew_source(ss, x) |
98 |
| - call this % iterate(system, x, ss, num_inner_iters) |
99 |
| - end if |
100 |
| - |
101 |
| - update_norm = norm2(x - xold) |
102 |
| - if (this % print_level .eq. -1) then |
103 |
| - write(13, *) iter, update_norm |
104 |
| - end if |
105 |
| - if (this % print_level .gt. 0) then |
106 |
| - print *, & |
107 |
| - & "outer iter ", iter, & |
108 |
| - & "num_inner_iters ", num_inner_iters, & |
109 |
| - & "update norm ", update_norm |
110 |
| - end if |
111 |
| - iter = iter + 1 |
112 |
| - |
113 |
| - end do outer_iterations |
114 |
| - |
115 |
| - if (this % print_level .eq. -1) then |
116 |
| - close(13) |
117 |
| - end if |
118 |
| - |
119 |
| - deallocate(xold) |
120 |
| - deallocate(ss) |
| 44 | +contains |
121 | 45 |
|
122 |
| - end subroutine solve |
123 |
| - |
124 | 46 | end module interface_linear_solver
|
0 commit comments