54 real(kind=
rp),
allocatable :: d(:)
55 real(kind=
rp),
allocatable :: w(:)
56 real(kind=
rp),
allocatable :: r(:)
57 real(kind=
rp) :: tha, dlt
58 integer :: power_its = 150
60 integer :: power_its_refresh = 20
62 logical :: warm_start_eigs = .false.
64 logical :: eigs_computed = .false.
66 real(kind=
rp),
allocatable :: ev(:)
67 logical :: recompute_eigs = .true.
68 logical :: zero_initial_guess = .false.
80 subroutine cheby_init(this, n, max_iter, M, rel_tol, abs_tol, monitor)
81 class(
cheby_t),
intent(inout),
target :: this
82 integer,
intent(in) :: max_iter
83 class(
pc_t),
optional,
intent(in),
target :: M
84 integer,
intent(in) :: n
85 real(kind=
rp),
optional,
intent(in) :: rel_tol
86 real(kind=
rp),
optional,
intent(in) :: abs_tol
87 logical,
optional,
intent(in) :: monitor
98 if (
present(rel_tol) .and.
present(abs_tol) .and.
present(monitor))
then
99 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
100 else if (
present(rel_tol) .and.
present(abs_tol))
then
101 call this%ksp_init(max_iter, rel_tol, abs_tol)
102 else if (
present(monitor) .and.
present(abs_tol))
then
103 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
104 else if (
present(rel_tol) .and.
present(monitor))
then
105 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
106 else if (
present(rel_tol))
then
107 call this%ksp_init(max_iter, rel_tol = rel_tol)
108 else if (
present(abs_tol))
then
109 call this%ksp_init(max_iter, abs_tol = abs_tol)
110 else if (
present(monitor))
then
111 call this%ksp_init(max_iter, monitor = monitor)
113 call this%ksp_init(max_iter)
119 class(
cheby_t),
intent(inout) :: this
120 if (
allocated(this%d))
then
124 if (
allocated(this%w))
then
128 if (
allocated(this%r))
then
131 if (
allocated(this%ev))
then
137 class(
cheby_t),
intent(inout) :: this
138 class(
ax_t),
intent(in) :: Ax
139 type(
field_t),
intent(inout) :: x
140 integer,
intent(in) :: n
141 type(
coef_t),
intent(inout) :: coef
143 type(
gs_t),
intent(inout) :: gs_h
144 real(kind=
rp) :: lam, b, a, rn
145 real(kind=
rp) :: boost = 1.1_rp
146 real(kind=
rp) :: lam_factor = 30.0_rp
147 real(kind=
rp) :: wtw, dtw, dtd
148 integer,
allocatable :: fixed_seed(:), saved_seed(:)
149 integer :: i, rnd_n, its
153 warm = this%warm_start_eigs .and. this%eigs_computed .and. &
155 associate(w => this%w, d => this%d, r => this%r)
158 its = this%power_its_refresh
159 call copy(d, this%ev, n)
164 call random_seed(
size = rnd_n)
165 allocate(saved_seed(rnd_n))
166 allocate(fixed_seed(rnd_n))
168 call random_seed(get = saved_seed)
169 call random_seed(put = fixed_seed)
172 call random_number(rn)
177 call random_seed(put = saved_seed)
179 call gs_h%op(d, n, gs_op_add)
180 call blst%apply(d, n)
185 call ax%compute(w, d, coef, x%msh, x%Xh)
186 call gs_h%op(w, n, gs_op_add)
187 call blst%apply(w, n)
188 if (
associated(this%schwarz))
then
189 call this%schwarz%compute(r, w)
192 call this%M%solve(r, w, n)
196 wtw =
glsc3(w, coef%mult, w, n)
197 call cmult2(d, w, 1.0_rp/sqrt(wtw), n)
198 call blst%apply(d, n)
201 call ax%compute(w, d, coef, x%msh, x%Xh)
202 call gs_h%op(w, n, gs_op_add)
203 call blst%apply(w, n)
204 if (
associated(this%schwarz))
then
205 call this%schwarz%compute(r, w)
208 call this%M%solve(r, w, n)
212 dtw =
glsc3(d, coef%mult, w, n)
213 dtd =
glsc3(d, coef%mult, d, n)
217 this%tha = (b+a)/2.0_rp
218 this%dlt = (b-a)/2.0_rp
220 if (this%warm_start_eigs)
then
221 if (.not.
allocated(this%ev))
then
222 allocate(this%ev(
size(this%d)))
224 call copy(this%ev, d, n)
226 this%eigs_computed = .true.
228 this%recompute_eigs = .false.
234 function cheby_solve(this, Ax, x, f, n, coef, blst, gs_h, niter) &
236 class(
cheby_t),
intent(inout) :: this
237 class(ax_t),
intent(in) :: ax
238 type(field_t),
intent(inout) :: x
239 integer,
intent(in) :: n
240 real(kind=rp),
dimension(n),
intent(in) :: f
241 type(coef_t),
intent(inout) :: coef
242 type(bc_list_t),
intent(inout) :: blst
243 type(gs_t),
intent(inout) :: gs_h
244 type(ksp_monitor_t) :: ksp_results
245 integer,
optional,
intent(in) :: niter
246 integer :: iter, max_iter
247 real(kind=rp) :: a, b, rtr, rnorm, norm_fac
249 if (this%recompute_eigs)
then
253 if (
present(niter))
then
256 max_iter = this%max_iter
258 norm_fac = 1.0_rp / sqrt(coef%volume)
260 associate( w => this%w, r => this%r, d => this%d)
263 call ax%compute(w, x%x, coef, x%msh, x%Xh)
264 call gs_h%op(w, n, gs_op_add)
265 call blst%apply(w, n)
268 rtr = glsc3(r, coef%mult, r, n)
269 rnorm = sqrt(rtr) * norm_fac
270 ksp_results%res_start = rnorm
271 ksp_results%res_final = rnorm
275 call this%M%solve(w, r, n)
277 a = 2.0_rp / this%tha
278 call add2s2(x%x, d, a, n)
281 do iter = 2, max_iter
284 call ax%compute(w, x%x, coef, x%msh, x%Xh)
285 call gs_h%op(w, n, gs_op_add)
286 call blst%apply(w, n)
289 call this%M%solve(w, r, n)
291 if (iter .eq. 2)
then
292 b = 0.5_rp * (this%dlt * a)**2
294 b = (this%dlt * a / 2.0_rp)**2
296 a = 1.0_rp/(this%tha - b/a)
297 call add2s1(d, w, b, n)
299 call add2s2(x%x, d, a, n)
304 call ax%compute(w, x%x, coef, x%msh, x%Xh)
305 call gs_h%op(w, n, gs_op_add)
306 call blst%apply(w, n)
308 rtr = glsc3(r, coef%mult, r, n)
309 rnorm = sqrt(rtr) * norm_fac
310 ksp_results%res_final = rnorm
311 ksp_results%iter = iter
312 ksp_results%converged = this%is_converged(iter, rnorm)
317 function cheby_impl(this, Ax, x, f, n, coef, blst, gs_h, niter) &
319 class(
cheby_t),
intent(inout) :: this
320 class(ax_t),
intent(in) :: ax
321 type(field_t),
intent(inout) :: x
322 integer,
intent(in) :: n
323 real(kind=rp),
dimension(n),
intent(in) :: f
324 type(coef_t),
intent(inout) :: coef
325 type(bc_list_t),
intent(inout) :: blst
326 type(gs_t),
intent(inout) :: gs_h
327 type(ksp_monitor_t) :: ksp_results
328 integer,
optional,
intent(in) :: niter
329 integer :: iter, max_iter, i
330 real(kind=rp) :: a, b, rtr, rnorm, norm_fac
331 real(kind=rp) :: rhok, rhokp1, sig1, tmp1, tmp2, inv_tha
333 if (this%recompute_eigs)
then
337 if (
present(niter))
then
340 max_iter = this%max_iter
342 norm_fac = 1.0_rp / sqrt(coef%volume)
344 associate( w => this%w, r => this%r, d => this%d)
346 if (.not.this%zero_initial_guess)
then
347 call ax%compute(w, x%x, coef, x%msh, x%Xh)
348 call gs_h%op(w, n, gs_op_add)
349 call blst%apply(w, n)
350 call sub3(r, f, w, n)
353 this%zero_initial_guess = .false.
357 if (
associated(this%schwarz))
then
358 call this%schwarz%compute(d, r)
360 call this%M%solve(d, r, n)
363 inv_tha = 1.0_rp / this%tha
370 d(i) = inv_tha * d(i)
371 x%x(i,1,1,1) = x%x(i,1,1,1) + d(i)
375 sig1 = this%tha / this%dlt
379 do iter = 2, max_iter
380 rhokp1 = 1.0_rp / (2.0_rp * sig1 - rhok)
382 tmp2 = 2.0_rp * rhokp1 / this%dlt
385 call ax%compute(w, x%x, coef, x%msh, x%Xh)
386 call gs_h%op(w, n, gs_op_add)
387 call blst%apply(w, n)
388 call sub3(r, f, w, n)
390 if (
associated(this%schwarz))
then
391 call this%schwarz%compute(w, r)
393 call this%M%solve(w, r, n)
401 d(i) = tmp1 * d(i) + tmp2 * w(i)
402 x%x(i,1,1,1) = x%x(i,1,1,1) + d(i)
412 n, coef, blstx, blsty, blstz, gs_h, niter)
result(ksp_results)
413 class(
cheby_t),
intent(inout) :: this
414 class(ax_t),
intent(in) :: ax
415 type(field_t),
intent(inout) :: x
416 type(field_t),
intent(inout) :: y
417 type(field_t),
intent(inout) :: z
418 integer,
intent(in) :: n
419 real(kind=rp),
dimension(n),
intent(in) :: fx
420 real(kind=rp),
dimension(n),
intent(in) :: fy
421 real(kind=rp),
dimension(n),
intent(in) :: fz
422 type(coef_t),
intent(inout) :: coef
423 type(bc_list_t),
intent(inout) :: blstx
424 type(bc_list_t),
intent(inout) :: blsty
425 type(bc_list_t),
intent(inout) :: blstz
426 type(gs_t),
intent(inout) :: gs_h
427 type(ksp_monitor_t),
dimension(3) :: ksp_results
428 integer,
optional,
intent(in) :: niter
430 ksp_results(1) = this%solve(ax, x, fx, n, coef, blstx, gs_h, niter)
431 ksp_results(2) = this%solve(ax, y, fy, n, coef, blsty, gs_h, niter)
432 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.
subroutine, public profiler_start_region(name, region_id)
Started a named (name) profiler region.
subroutine, public profiler_end_region(name, region_id)
End the most recently started profiler region.
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.