51 real(kind=
rp),
allocatable :: w(:)
52 real(kind=
rp),
allocatable :: r(:)
53 real(kind=
rp),
allocatable :: p(:)
54 real(kind=
rp),
allocatable :: z(:)
65 subroutine sx_cg_init(this, n, max_iter, M, rel_tol, abs_tol, monitor)
66 class(
sx_cg_t),
target,
intent(inout) :: this
67 class(
pc_t),
optional,
intent(in),
target :: M
68 integer,
intent(in) :: n
69 integer,
intent(in) :: max_iter
70 real(kind=
rp),
optional,
intent(in) :: rel_tol
71 real(kind=
rp),
optional,
intent(in) :: abs_tol
72 logical,
optional,
intent(in) :: monitor
85 if (
present(rel_tol) .and.
present(abs_tol) .and.
present(monitor))
then
86 call this%ksp_init(max_iter, rel_tol, abs_tol, monitor = monitor)
87 else if (
present(rel_tol) .and.
present(abs_tol))
then
88 call this%ksp_init(max_iter, rel_tol, abs_tol)
89 else if (
present(monitor) .and.
present(abs_tol))
then
90 call this%ksp_init(max_iter, abs_tol = abs_tol, monitor = monitor)
91 else if (
present(rel_tol) .and.
present(monitor))
then
92 call this%ksp_init(max_iter, rel_tol, monitor = monitor)
93 else if (
present(rel_tol))
then
94 call this%ksp_init(max_iter, rel_tol = rel_tol)
95 else if (
present(abs_tol))
then
96 call this%ksp_init(max_iter, abs_tol = abs_tol)
97 else if (
present(monitor))
then
98 call this%ksp_init(max_iter, monitor = monitor)
100 call this%ksp_init(max_iter)
107 class(
sx_cg_t),
intent(inout) :: this
111 if (
allocated(this%w))
then
115 if (
allocated(this%r))
then
119 if (
allocated(this%p))
then
123 if (
allocated(this%z))
then
132 function sx_cg_solve(this, Ax, x, f, n, coef, bc_projector, gs_h, niter) &
134 class(
sx_cg_t),
intent(inout) :: this
135 class(
ax_t),
intent(in) :: ax
136 type(
field_t),
intent(inout) :: x
137 integer,
intent(in) :: n
138 real(kind=
rp),
dimension(n),
intent(in) :: f
139 type(
coef_t),
intent(inout) :: coef
141 type(
gs_t),
intent(inout) :: gs_h
143 integer,
optional,
intent(in) :: niter
144 real(kind=
rp),
parameter :: one = 1.0
145 real(kind=
rp),
parameter :: zero = 0.0
146 integer :: i, iter, max_iter
147 real(kind=
rp) :: rnorm, rtr, rtr0, rtz2, rtz1
148 real(kind=
rp) :: beta, pap, alpha, alphm, norm_fac
150 if (
present(niter))
then
153 max_iter = this%max_iter
155 norm_fac = one / sqrt(coef%volume)
159 x%x(i,1,1,1) = 0.0_rp
164 rtr =
glsc3(this%r, coef%mult, this%r, n)
165 rnorm = sqrt(rtr)*norm_fac
166 ksp_results%res_start = rnorm
167 ksp_results%res_final = rnorm
169 if (
abscmp(rnorm, zero))
then
170 ksp_results%converged = .true.
174 call this%monitor_start(
'CG')
175 do iter = 1, max_iter
176 call this%M%solve(this%z, this%r, n)
178 rtz1 =
glsc3(this%r, coef%mult, this%z, n)
181 if (iter .eq. 1) beta = zero
182 call add2s1(this%p, this%z, beta, n)
184 call ax%compute(this%w, this%p, coef, x%msh, x%Xh)
185 call gs_h%op(this%w, n, gs_op_add)
186 call bc_projector%apply(this%w, n)
188 pap =
glsc3(this%w, coef%mult, this%p, n)
193 x%x(i,1,1,1) = x%x(i,1,1,1) + alpha * this%p(i)
194 this%r(i) = this%r(i) + alphm * this%w(i)
197 rtr =
glsc3(this%r, coef%mult, this%r, n)
198 if (iter .eq. 1) rtr0 = rtr
199 rnorm = sqrt(rtr) * norm_fac
200 call this%monitor_iter(iter, rnorm)
201 if (rnorm .lt. this%abs_tol)
then
205 call this%monitor_stop()
206 ksp_results%res_final = rnorm
207 ksp_results%iter = iter
208 ksp_results%converged = this%is_converged(iter, rnorm)
213 n, coef, bc_projector, gs_h, niter)
result(ksp_results)
214 class(
sx_cg_t),
intent(inout) :: this
215 class(
ax_t),
intent(in) :: ax
216 type(
field_t),
intent(inout) :: x
217 type(
field_t),
intent(inout) :: y
218 type(
field_t),
intent(inout) :: z
219 integer,
intent(in) :: n
220 real(kind=
rp),
dimension(n),
intent(in) :: fx
221 real(kind=
rp),
dimension(n),
intent(in) :: fy
222 real(kind=
rp),
dimension(n),
intent(in) :: fz
223 type(
coef_t),
intent(inout) :: coef
225 type(
gs_t),
intent(inout) :: gs_h
227 integer,
optional,
intent(in) :: niter
231 ksp_results(1) = this%solve(ax, x, fx, n, coef, bc_x, gs_h, niter)
232 ksp_results(2) = this%solve(ax, y, fy, n, coef, bc_y, gs_h, niter)
233 ksp_results(3) = this%solve(ax, z, fz, n, coef, bc_z, 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.
Defines various Conjugate Gradient methods.
type(ksp_monitor_t) function, dimension(3) sx_cg_solve_coupled(this, ax, x, y, z, fx, fy, fz, n, coef, bc_projector, gs_h, niter)
Standard PCG coupled solve.
subroutine sx_cg_free(this)
Deallocate a standard PCG solver.
type(ksp_monitor_t) function sx_cg_solve(this, ax, x, f, n, coef, bc_projector, gs_h, niter)
Standard PCG solve.
subroutine sx_cg_init(this, n, max_iter, m, rel_tol, abs_tol, monitor)
Initialise a standard PCG solver.
Implements the base abstract type for Krylov solvers plus helper types.
integer, parameter, public ksp_max_iter
Maximum number of iters.
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)
integer, parameter, public rp
Global precision used in computations.
Implements scalar_projector_t.
Implements boundary condition projectors for vector fields. Two types concrete types are provided: se...
subroutine, public vector_bc_projector_components(this, x, y, z)
Access the component scalar projectors from a segregated vector projector.
Base type for a matrix-vector product providing .
Standard preconditioned conjugate gradient method (SX version)
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.
Projector for scalar boundary conditions.
Abstract type for resolving vector boundary conditions.