61 krylov_solver_factory, krylov_solver_destroy
63 use,
intrinsic :: iso_c_binding
72 type(
gs_t),
pointer :: gs_h
92 class(
ax_t),
allocatable :: ax
104 subroutine phmg_init(this, msh, Xh, coef, dof, gs_h, bclst)
105 class(
phmg_t),
intent(inout),
target :: this
106 type(
mesh_t),
intent(inout),
target :: msh
107 type(
space_t),
intent(inout),
target :: Xh
108 type(
coef_t),
intent(in),
target :: coef
109 type(
dofmap_t),
intent(in),
target :: dof
110 type(
gs_t),
intent(inout),
target :: gs_h
111 type(
bc_list_t),
intent(inout),
target :: bclst
112 integer :: lx_crs, lx_mid
113 integer,
allocatable :: lx_lvls(:)
115 class(
bc_t),
pointer :: bc_j
116 logical :: use_jacobi, use_cheby
122 this%nlvls = xh%lx - 1
124 allocate(lx_lvls(0:this%nlvls - 1))
125 do i = 1, this%nlvls -1
126 lx_lvls(i) = xh%lx - i
129 allocate(this%phmg_hrchy%lvl(0:this%nlvls - 1))
131 this%phmg_hrchy%lvl(0)%lvl = 0
132 this%phmg_hrchy%lvl(0)%Xh => xh
133 this%phmg_hrchy%lvl(0)%coef => coef
134 this%phmg_hrchy%lvl(0)%dm_Xh => dof
135 this%phmg_hrchy%lvl(0)%gs_h => gs_h
137 do i = 1, this%nlvls - 1
138 allocate(this%phmg_hrchy%lvl(i)%Xh)
139 allocate(this%phmg_hrchy%lvl(i)%dm_Xh)
140 allocate(this%phmg_hrchy%lvl(i)%gs_h)
141 allocate(this%phmg_hrchy%lvl(i)%coef)
143 this%phmg_hrchy%lvl(i)%lvl = i
144 call this%phmg_hrchy%lvl(i)%Xh%init(
gll, lx_lvls(i), lx_lvls(i), &
146 call this%phmg_hrchy%lvl(i)%dm_Xh%init(msh, this%phmg_hrchy%lvl(i)%Xh)
147 call this%phmg_hrchy%lvl(i)%gs_h%init(this%phmg_hrchy%lvl(i)%dm_Xh)
148 call this%phmg_hrchy%lvl(i)%coef%init(this%phmg_hrchy%lvl(i)%gs_h)
151 do i = 0, this%nlvls - 1
152 call this%phmg_hrchy%lvl(i)%r%init(this%phmg_hrchy%lvl(i)%dm_Xh)
153 call this%phmg_hrchy%lvl(i)%w%init(this%phmg_hrchy%lvl(i)%dm_Xh)
154 call this%phmg_hrchy%lvl(i)%z%init(this%phmg_hrchy%lvl(i)%dm_Xh)
158 call this%phmg_hrchy%lvl(i)%cheby_device%init(this%phmg_hrchy%lvl(i)%dm_Xh%size(),
ksp_max_iter)
160 call this%phmg_hrchy%lvl(i)%cheby%init(this%phmg_hrchy%lvl(i)%dm_Xh%size(),
ksp_max_iter)
166 call this%phmg_hrchy%lvl(i)%device_jacobi%init(this%phmg_hrchy%lvl(i)%coef, &
167 this%phmg_hrchy%lvl(i)%dm_Xh, &
168 this%phmg_hrchy%lvl(i)%gs_h)
170 call this%phmg_hrchy%lvl(i)%jacobi%init(this%phmg_hrchy%lvl(i)%coef, &
171 this%phmg_hrchy%lvl(i)%dm_Xh, &
172 this%phmg_hrchy%lvl(i)%gs_h)
176 this%phmg_hrchy%lvl(i)%coef%ifh2 = coef%ifh2
177 call copy(this%phmg_hrchy%lvl(i)%coef%h1, coef%h1, &
178 this%phmg_hrchy%lvl(i)%dm_Xh%size())
180 call this%phmg_hrchy%lvl(i)%bc%init_base(this%phmg_hrchy%lvl(i)%coef)
181 if (bclst%size() .gt. 0 )
then
182 do j = 1, bclst%size()
184 call this%phmg_hrchy%lvl(i)%bc%mark_facets(bc_j%marked_facet)
187 call this%phmg_hrchy%lvl(i)%bc%finalize()
188 call this%phmg_hrchy%lvl(i)%bc%set_g(0.0_rp)
189 call this%phmg_hrchy%lvl(i)%bclst%init()
190 call this%phmg_hrchy%lvl(i)%bclst%append(this%phmg_hrchy%lvl(i)%bc)
194 call ax_helm_factory(this%ax, full_formulation = .false.)
197 allocate(this%intrp(this%nlvls - 1))
198 do i = 1, this%nlvls -1
199 call this%intrp(i)%init(this%phmg_hrchy%lvl(i-1)%Xh, &
200 this%phmg_hrchy%lvl(i)%Xh)
203 call this%amg_solver%init(this%ax, this%phmg_hrchy%lvl(this%nlvls -1)%Xh, &
204 this%phmg_hrchy%lvl(this%nlvls -1)%coef, this%msh, &
205 this%phmg_hrchy%lvl(this%nlvls-1)%gs_h, 4, &
206 this%phmg_hrchy%lvl(this%nlvls -1)%bclst, 1)
104 subroutine phmg_init(this, msh, Xh, coef, dof, gs_h, bclst)
…
211 class(
phmg_t),
intent(inout) :: this
215 class(
phmg_t),
intent(inout) :: this
216 integer,
intent(in) :: n
217 real(kind=
rp),
dimension(n),
intent(inout) :: z
218 real(kind=
rp),
dimension(n),
intent(inout) :: r
219 type(c_ptr) :: z_d, r_d
223 associate( mglvl => this%phmg_hrchy%lvl)
231 call phmg_mg_cycle(mglvl(0)%z, mglvl(0)%r, mglvl(0)%w, 0, this%nlvls -1, &
232 mglvl, this%intrp, this%msh, this%Ax, this%amg_solver)
236 call copy(mglvl(0)%r%x, r, n)
238 mglvl(0)%z%x = 0.0_rp
239 mglvl(0)%w%x = 0.0_rp
241 call phmg_mg_cycle(mglvl(0)%z, mglvl(0)%r, mglvl(0)%w, 0, this%nlvls -1, &
242 mglvl, this%intrp, this%msh, this%Ax, this%amg_solver)
244 call copy(z, mglvl(0)%z%x, n)
251 class(
phmg_t),
intent(inout) :: this
256 mg, intrp, msh, Ax, amg_solver)
257 type(ksp_monitor_t) :: ksp_results
260 type(interpolator_t) :: intrp(1:clvl)
261 type(tamg_solver_t),
intent(inout) :: amg_solver
262 class(ax_t),
intent(inout) :: ax
263 type(mesh_t),
intent(inout) :: msh
264 type(field_t) :: z, r, w
268 call profiler_start_region(
'PHMG_cycle', 8)
272 call profiler_start_region(
'PHMG_PreSmooth', 9)
276 if (neko_bcknd_device .eq. 1)
then
277 ksp_results = mg(lvl)%cheby_device%solve(ax, z, &
278 r%x, mg(lvl)%dm_Xh%size(), &
279 mg(lvl)%coef, mg(lvl)%bclst, &
280 mg(lvl)%gs_h, niter = 11)
282 ksp_results = mg(lvl)%cheby%solve(ax, z, &
283 r%x, mg(lvl)%dm_Xh%size(), &
284 mg(lvl)%coef, mg(lvl)%bclst, &
285 mg(lvl)%gs_h, niter = 15)
287 call profiler_end_region(
'PHMG_PreSmooth', 9)
292 call ax%compute(w%x, z%x, mg(lvl)%coef, msh, mg(lvl)%Xh)
293 call mg(lvl)%gs_h%op(w%x, mg(lvl)%dm_Xh%size(), gs_op_add)
296 if (neko_bcknd_device .eq. 1)
then
297 call device_sub3(w%x_d, r%x_d, w%x_d, mg(lvl)%dm_Xh%size())
305 if (neko_bcknd_device .eq. 1)
then
306 call device_col2(w%x_d, mg(lvl)%coef%mult_d, mg(lvl)%dm_Xh%size())
308 call col2(w%x, mg(lvl)%coef%mult, mg(lvl)%dm_Xh%size())
311 call profiler_start_region(
'PHMG_map_to_coarse', 9)
312 call intrp(lvl+1)%map(mg(lvl+1)%r%x, w%x, msh%nelv, mg(lvl+1)%Xh)
313 call profiler_end_region(
'PHMG_map_to_coarse', 9)
315 call mg(lvl+1)%gs_h%op(mg(lvl+1)%r%x, mg(lvl+1)%dm_Xh%size(), gs_op_add)
317 call mg(lvl+1)%bclst%apply_scalar( &
319 mg(lvl+1)%dm_Xh%size())
323 if (neko_bcknd_device .eq. 1)
then
324 call device_rzero(mg(lvl+1)%z%x_d, mg(lvl+1)%dm_Xh%size())
326 mg(lvl+1)%z%x = 0.0_rp
328 if (lvl+1 .eq. clvl)
then
329 call profiler_start_region(
'PHMG_tAMG_coarse_grid', 10)
331 if (neko_bcknd_device .eq. 1)
then
332 call amg_solver%device_solve(mg(lvl+1)%z%x, &
336 mg(lvl+1)%dm_Xh%size())
338 call amg_solver%solve(mg(lvl+1)%z%x, &
340 mg(lvl+1)%dm_Xh%size())
342 call profiler_end_region(
'PHMG_tAMG_coarse_grid', 10)
344 call mg(lvl+1)%bclst%apply_scalar( &
346 mg(lvl+1)%dm_Xh%size())
348 call phmg_mg_cycle(mg(lvl+1)%z, mg(lvl+1)%r, mg(lvl+1)%w, lvl+1, &
349 clvl, mg, intrp, msh, ax, amg_solver)
355 call profiler_start_region(
'PHMG_map_to_fine', 9)
356 call intrp(lvl+1)%map(w%x, mg(lvl+1)%z%x, msh%nelv, mg(lvl)%Xh)
357 call profiler_end_region(
'PHMG_map_to_fine', 9)
359 call mg(lvl)%gs_h%op(w%x, mg(lvl)%dm_Xh%size(), gs_op_add)
361 if (neko_bcknd_device .eq. 1)
then
362 call device_col2(w%x_d, mg(lvl)%coef%mult_d, mg(lvl)%dm_Xh%size())
364 call col2(w%x, mg(lvl)%coef%mult, mg(lvl)%dm_Xh%size())
367 call mg(lvl)%bclst%apply_scalar(w%x, mg(lvl)%dm_Xh%size())
372 if (neko_bcknd_device .eq. 1)
then
373 call device_add2(z%x_d, w%x_d, mg(lvl)%dm_Xh%size())
381 call profiler_start_region(
'PHMG_PostSmooth', 9)
385 if (neko_bcknd_device .eq. 1)
then
386 ksp_results = mg(lvl)%cheby_device%solve(ax, z, &
387 r%x, mg(lvl)%dm_Xh%size(), &
388 mg(lvl)%coef, mg(lvl)%bclst, &
389 mg(lvl)%gs_h, niter = 11)
391 ksp_results = mg(lvl)%cheby%solve(ax, z, &
392 r%x, mg(lvl)%dm_Xh%size(), &
393 mg(lvl)%coef, mg(lvl)%bclst, &
394 mg(lvl)%gs_h, niter = 15)
396 call profiler_end_region(
'PHMG_PostSmooth', 9)
398 call profiler_end_region(
'PHMG_cycle', 8)
403 class(ax_t),
intent(inout) :: Ax
404 type(mesh_t),
intent(inout) :: msh
405 type(field_t),
intent(inout) :: z, r, w
406 integer,
intent(in) :: n, lvl
407 integer :: i, iblk, ni, niblk
413 call ax%compute(w%x, z%x, mg%coef, msh, mg%Xh)
414 call mg%gs_h%op(w%x, n, gs_op_add)
415 call mg%bclst%apply_scalar(w%x, n)
416 call device_sub3(w%x_d, r%x_d, w%x_d, n)
418 call mg%device_jacobi%solve(w%x, w%x, n)
420 call device_add2s2(z%x_d, w%x_d, 0.8_rp, n)
423 call ax%compute(w%x, z%x, mg%coef, msh, mg%Xh)
424 call device_invcol2(w%x_d, mg%coef%mult_d, n)
425 call device_sub3(w%x_d, r%x_d, w%x_d, n)
426 call mg%device_jacobi%solve(w%x, w%x, n)
427 call device_add2s2(z%x_d, w%x_d, 0.8_rp, n)
436 class(ax_t),
intent(inout) :: Ax
437 type(mesh_t),
intent(inout) :: msh
438 type(field_t) :: z, r, w
440 character(len=LOG_SIZE) :: log_buf
441 call ax%compute(w%x, z%x, mg%coef, msh, mg%Xh)
442 call mg%gs_h%op(w%x, mg%dm_Xh%size(), gs_op_add)
443 call mg%bclst%apply_scalar(w%x, mg%dm_Xh%size())
444 call device_sub3(w%x_d, r%x_d, w%x_d, mg%dm_Xh%size())
445 val = device_glsc2(w%x_d, w%x_d, mg%dm_Xh%size())
447 write(log_buf,
'(A15,I4,F12.6)')
'PRESMOO - PRE', lvl, val
448 else if (typ .eq. 2)
then
449 write(log_buf,
'(A15,I4,F12.6)')
'PRESMOO -POST', lvl, val
450 else if (typ .eq. 3)
then
451 write(log_buf,
'(A15,I4,F12.6)')
'POSTSMOO- PRE', lvl, val
452 else if (typ .eq. 4)
then
453 write(log_buf,
'(A15,I4,F12.6)')
'POSTSMOO-POST', lvl, val
454 else if (typ .eq. 5)
then
455 write(log_buf,
'(A15,I4,F12.6)')
'TAMG - PRE', lvl, val
456 else if (typ .eq. 6)
then
457 write(log_buf,
'(A15,I4,F12.6)')
'TAMG -POST', lvl, val
459 write(log_buf,
'(A15,I4,F12.6)')
'RESID', lvl, val
461 call neko_log%message(log_buf)
Return the device pointer for an associated Fortran array.
Defines a Matrix-vector product.
Defines a boundary condition.
Chebyshev preconditioner.
Chebyshev preconditioner.
Jacobi preconditioner accelerator backend.
subroutine, public device_add2(a_d, b_d, n)
Vector addition .
subroutine, public device_col2(a_d, b_d, n)
Vector multiplication .
subroutine, public device_rzero(a_d, n)
Zero a real vector.
subroutine, public device_add2s2(a_d, b_d, c1, n)
Vector addition with scalar multiplication (multiplication on first argument)
real(kind=rp) function, public device_glsc2(a_d, b_d, n)
Weighted inner product .
subroutine, public device_sub3(a_d, b_d, c_d, n)
Vector subtraction .
subroutine, public device_copy(a_d, b_d, n)
Copy a vector .
subroutine, public device_invcol2(a_d, b_d, n)
Vector division .
Device abstraction, common interface for various accelerators.
Defines a dirichlet boundary condition.
Defines a mapping of the degrees of freedom.
Routines to interpolate between different spaces.
Implements the base abstract type for Krylov solvers plus helper types.
integer, parameter, public ksp_max_iter
Maximum number of iters.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
subroutine, public add2(a, b, n)
Vector addition .
subroutine, public col2(a, b, n)
Vector multiplication .
subroutine, public copy(a, b, n)
Copy a vector .
integer, parameter neko_bcknd_device
integer, parameter, public rp
Global precision used in computations.
Hybrid ph-multigrid preconditioner.
subroutine phmg_jacobi_smoother(z, r, w, mg, msh, ax, n, lvl)
subroutine phmg_solve(this, z, r, n)
subroutine phmg_init(this, msh, xh, coef, dof, gs_h, bclst)
subroutine phmg_update(this)
subroutine phmg_free(this)
subroutine phmg_resid_monitor(z, r, w, mg, msh, ax, lvl, typ)
recursive subroutine phmg_mg_cycle(z, r, w, lvl, clvl, mg, intrp, msh, ax, amg_solver)
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.
Defines a function space.
integer, parameter, public gll
Implements multigrid using the TreeAMG hierarchy structure. USE:
Base type for a matrix-vector product providing .
Base type for a boundary condition.
A list of allocatable `bc_t`. Follows the standard interface of lists.
Defines a Chebyshev preconditioner.
Defines a Chebyshev preconditioner.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
Defines a jacobi preconditioner.
Generic Dirichlet boundary condition on .
Interpolation between two space::space_t.
Defines a jacobi preconditioner.
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.
Type for the TreeAMG solver.