53 real(kind=
rp),
allocatable :: d(:)
54 real(kind=
rp),
allocatable :: w(:)
55 real(kind=
rp),
allocatable :: r(:)
56 real(kind=
rp) :: tha, dlt
57 integer :: power_its = 150
58 logical :: recompute_eigs = .true.
59 logical :: zero_initial_guess = .false.
71 subroutine cheby_init(this, n, max_iter, M, rel_tol, abs_tol, monitor)
72 class(
cheby_t),
intent(inout),
target :: this
73 integer,
intent(in) :: max_iter
74 class(
pc_t),
optional,
intent(in),
target :: M
75 integer,
intent(in) :: n
76 real(kind=
rp),
optional,
intent(in) :: rel_tol
77 real(kind=
rp),
optional,
intent(in) :: abs_tol
78 logical,
optional,
intent(in) :: monitor
89 if (
present(rel_tol) .and.
present(abs_tol) .and.
present(monitor))
then
90 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
91 else if (
present(rel_tol) .and.
present(abs_tol))
then
92 call this%ksp_init(max_iter, rel_tol, abs_tol)
93 else if (
present(monitor) .and.
present(abs_tol))
then
94 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
95 else if (
present(rel_tol) .and.
present(monitor))
then
96 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
97 else if (
present(rel_tol))
then
98 call this%ksp_init(max_iter, rel_tol = rel_tol)
99 else if (
present(abs_tol))
then
100 call this%ksp_init(max_iter, abs_tol = abs_tol)
101 else if (
present(monitor))
then
102 call this%ksp_init(max_iter, monitor = monitor)
104 call this%ksp_init(max_iter)
110 class(
cheby_t),
intent(inout) :: this
111 if (
allocated(this%d))
then
115 if (
allocated(this%w))
then
119 if (
allocated(this%r))
then
125 class(
cheby_t),
intent(inout) :: this
126 class(
ax_t),
intent(in) :: Ax
127 type(
field_t),
intent(inout) :: x
128 integer,
intent(in) :: n
129 type(
coef_t),
intent(inout) :: coef
131 type(
gs_t),
intent(inout) :: gs_h
132 real(kind=
rp) :: lam, b, a, rn
133 real(kind=
rp) :: boost = 1.1_rp
134 real(kind=
rp) :: lam_factor = 30.0_rp
135 real(kind=
rp) :: wtw, dtw, dtd
136 integer,
allocatable :: fixed_seed(:), saved_seed(:)
138 associate(w => this%w, d => this%d, r => this%r)
141 call random_seed( size=rnd_n )
142 allocate(saved_seed(rnd_n))
143 allocate(fixed_seed(rnd_n))
145 call random_seed( get=saved_seed )
146 call random_seed( put=fixed_seed )
149 call random_number(rn)
154 call random_seed( put=saved_seed )
156 call gs_h%op(d, n, gs_op_add)
157 call blst%apply(d, n)
160 do i = 1, this%power_its
161 call ax%compute(w, d, coef, x%msh, x%Xh)
162 call gs_h%op(w, n, gs_op_add)
163 call blst%apply(w, n)
164 if (
associated(this%schwarz))
then
165 call this%schwarz%compute(r, w)
168 call this%M%solve(r, w, n)
172 wtw =
glsc3(w, coef%mult, w, n)
173 call cmult2(d, w, 1.0_rp/sqrt(wtw), n)
174 call blst%apply(d, n)
177 call ax%compute(w, d, coef, x%msh, x%Xh)
178 call gs_h%op(w, n, gs_op_add)
179 call blst%apply(w, n)
180 if (
associated(this%schwarz))
then
181 call this%schwarz%compute(r, w)
184 call this%M%solve(r, w, n)
188 dtw =
glsc3(d, coef%mult, w, n)
189 dtd =
glsc3(d, coef%mult, d, n)
193 this%tha = (b+a)/2.0_rp
194 this%dlt = (b-a)/2.0_rp
196 this%recompute_eigs = .false.
201 function cheby_solve(this, Ax, x, f, n, coef, blst, gs_h, niter) &
203 class(
cheby_t),
intent(inout) :: this
204 class(ax_t),
intent(in) :: ax
205 type(field_t),
intent(inout) :: x
206 integer,
intent(in) :: n
207 real(kind=rp),
dimension(n),
intent(in) :: f
208 type(coef_t),
intent(inout) :: coef
209 type(bc_list_t),
intent(inout) :: blst
210 type(gs_t),
intent(inout) :: gs_h
211 type(ksp_monitor_t) :: ksp_results
212 integer,
optional,
intent(in) :: niter
213 integer :: iter, max_iter
214 real(kind=rp) :: a, b, rtr, rnorm, norm_fac
216 if (this%recompute_eigs)
then
220 if (
present(niter))
then
223 max_iter = this%max_iter
225 norm_fac = 1.0_rp / sqrt(coef%volume)
227 associate( w => this%w, r => this%r, d => this%d)
230 call ax%compute(w, x%x, coef, x%msh, x%Xh)
231 call gs_h%op(w, n, gs_op_add)
232 call blst%apply(w, n)
235 rtr = glsc3(r, coef%mult, r, n)
236 rnorm = sqrt(rtr) * norm_fac
237 ksp_results%res_start = rnorm
238 ksp_results%res_final = rnorm
242 call this%M%solve(w, r, n)
244 a = 2.0_rp / this%tha
245 call add2s2(x%x, d, a, n)
248 do iter = 2, max_iter
251 call ax%compute(w, x%x, coef, x%msh, x%Xh)
252 call gs_h%op(w, n, gs_op_add)
253 call blst%apply(w, n)
256 call this%M%solve(w, r, n)
258 if (iter .eq. 2)
then
259 b = 0.5_rp * (this%dlt * a)**2
261 b = (this%dlt * a / 2.0_rp)**2
263 a = 1.0_rp/(this%tha - b/a)
264 call add2s1(d, w, b, n)
266 call add2s2(x%x, d, a, n)
271 call ax%compute(w, x%x, coef, x%msh, x%Xh)
272 call gs_h%op(w, n, gs_op_add)
273 call blst%apply(w, n)
275 rtr = glsc3(r, coef%mult, r, n)
276 rnorm = sqrt(rtr) * norm_fac
277 ksp_results%res_final = rnorm
278 ksp_results%iter = iter
279 ksp_results%converged = this%is_converged(iter, rnorm)
284 function cheby_impl(this, Ax, x, f, n, coef, blst, gs_h, niter) &
286 class(
cheby_t),
intent(inout) :: this
287 class(ax_t),
intent(in) :: ax
288 type(field_t),
intent(inout) :: x
289 integer,
intent(in) :: n
290 real(kind=rp),
dimension(n),
intent(in) :: f
291 type(coef_t),
intent(inout) :: coef
292 type(bc_list_t),
intent(inout) :: blst
293 type(gs_t),
intent(inout) :: gs_h
294 type(ksp_monitor_t) :: ksp_results
295 integer,
optional,
intent(in) :: niter
296 integer :: iter, max_iter, i
297 real(kind=rp) :: a, b, rtr, rnorm, norm_fac
298 real(kind=rp) :: rhok, rhokp1, sig1, tmp1, tmp2
300 if (this%recompute_eigs)
then
304 if (
present(niter))
then
307 max_iter = this%max_iter
309 norm_fac = 1.0_rp / sqrt(coef%volume)
311 associate( w => this%w, r => this%r, d => this%d)
313 if (.not.this%zero_initial_guess)
then
314 call ax%compute(w, x%x, coef, x%msh, x%Xh)
315 call gs_h%op(w, n, gs_op_add)
316 call blst%apply(w, n)
317 call sub3(r, f, w, n)
320 this%zero_initial_guess = .false.
324 if (
associated(this%schwarz))
then
325 call this%schwarz%compute(d, r)
327 call this%M%solve(d, r, n)
330 do concurrent(i = 1:n)
331 d(i) = 1.0_rp/this%tha * d(i)
332 x%x(i,1,1,1) = x%x(i,1,1,1) + d(i)
335 sig1 = this%tha / this%dlt
339 do iter = 2, max_iter
340 rhokp1 = 1.0_rp / (2.0_rp * sig1 - rhok)
342 tmp2 = 2.0_rp * rhokp1 / this%dlt
345 call ax%compute(w, x%x, coef, x%msh, x%Xh)
346 call gs_h%op(w, n, gs_op_add)
347 call blst%apply(w, n)
348 call sub3(r, f, w, n)
350 if (
associated(this%schwarz))
then
351 call this%schwarz%compute(w, r)
353 call this%M%solve(w, r, n)
355 do concurrent(i = 1:n)
356 d(i) = tmp1 * d(i) + tmp2 * w(i)
357 x%x(i,1,1,1) = x%x(i,1,1,1) + d(i)
366 n, coef, blstx, blsty, blstz, gs_h, niter)
result(ksp_results)
367 class(
cheby_t),
intent(inout) :: this
368 class(ax_t),
intent(in) :: ax
369 type(field_t),
intent(inout) :: x
370 type(field_t),
intent(inout) :: y
371 type(field_t),
intent(inout) :: z
372 integer,
intent(in) :: n
373 real(kind=rp),
dimension(n),
intent(in) :: fx
374 real(kind=rp),
dimension(n),
intent(in) :: fy
375 real(kind=rp),
dimension(n),
intent(in) :: fz
376 type(coef_t),
intent(inout) :: coef
377 type(bc_list_t),
intent(inout) :: blstx
378 type(bc_list_t),
intent(inout) :: blsty
379 type(bc_list_t),
intent(inout) :: blstz
380 type(gs_t),
intent(inout) :: gs_h
381 type(ksp_monitor_t),
dimension(3) :: ksp_results
382 integer,
optional,
intent(in) :: niter
384 ksp_results(1) = this%solve(ax, x, fx, n, coef, blstx, gs_h, niter)
385 ksp_results(2) = this%solve(ax, y, fy, n, coef, blsty, gs_h, niter)
386 ksp_results(3) = this%solve(ax, z, fz, n, coef, blstz, gs_h, niter)
__device__ T solve(const T u, const T y, const T guess, const T nu, const T kappa, const T B)
Defines a Matrix-vector product.
Chebyshev preconditioner.
type(ksp_monitor_t) function cheby_impl(this, ax, x, f, n, coef, blst, gs_h, niter)
A chebyshev preconditioner.
subroutine cheby_free(this)
type(ksp_monitor_t) function, dimension(3) cheby_solve_coupled(this, ax, x, y, z, fx, fy, fz, n, coef, blstx, blsty, blstz, gs_h, niter)
Standard Chebyshev coupled solve.
subroutine cheby_init(this, n, max_iter, m, rel_tol, abs_tol, monitor)
Initialise a standard solver.
subroutine cheby_power(this, ax, x, n, coef, blst, gs_h)
type(ksp_monitor_t) function cheby_solve(this, ax, x, f, n, coef, blst, gs_h, niter)
A chebyshev preconditioner.
Implements the base abstract type for Krylov solvers plus helper types.
subroutine, public cmult(a, c, n)
Multiplication by constant c .
subroutine, public cmult2(a, b, c, n)
Multiplication by constant c .
real(kind=rp) function, public glsc3(a, b, c, n)
Weighted inner product .
subroutine, public add2s1(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on first argument)
real(kind=rp) function, public glsc2(a, b, n)
Weighted inner product .
subroutine, public rone(a, n)
Set all elements to one.
subroutine, public sub3(a, b, c, n)
Vector subtraction .
subroutine, public add2(a, b, n)
Vector addition .
subroutine, public copy(a, b, n)
Copy a vector .
subroutine, public rzero(a, n)
Zero a real vector.
subroutine, public sub2(a, b, n)
Vector substraction .
subroutine, public add2s2(a, b, c1, n)
Vector addition with scalar multiplication (multiplication on second argument)
integer, parameter, public rp
Global precision used in computations.
Overlapping schwarz solves.
Defines a function space.
Base type for a matrix-vector product providing .
A list of allocatable `bc_t`. Follows the standard interface of lists.
Defines a Chebyshev preconditioner.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Type for storing initial and final residuals in a Krylov solver.
Base abstract type for a canonical Krylov method, solving .
Defines a canonical Krylov preconditioner.
The function space for the SEM solution fields.