141 subroutine hsmg_init(this, msh, Xh, coef, dof, gs_h, bclst, crs_pctype)
142 class(
hsmg_t),
intent(inout),
target :: this
143 type(
mesh_t),
intent(inout),
target :: msh
144 type(
space_t),
intent(inout),
target :: Xh
145 type(
coef_t),
intent(in),
target :: coef
146 type(
dofmap_t),
intent(in),
target :: dof
147 type(
gs_t),
intent(inout),
target :: gs_h
148 type(
bc_list_t),
intent(inout),
target :: bclst
149 character(len=*),
optional :: crs_pctype
151 integer :: lx_crs, lx_mid
152 class(
bc_t),
pointer :: bc_i
157 if (xh%lx .lt. 5)
then
158 lx_mid =
max(xh%lx-1,3)
160 if (xh%lx .le. 2)
then
161 call neko_error(
'Polynomial order < 2 not supported for hsmg precon')
168 allocate(this%grids(this%nlvls))
169 allocate(this%w(dof%size()))
170 allocate(this%r(dof%size()))
174 call msh%all_deformed()
177 call this%e%init(dof,
'work array')
178 call this%wf%init(dof,
'work 2')
180 call this%Xh_crs%init(
gll, lx_crs, lx_crs, lx_crs)
181 call this%dm_crs%init(msh, this%Xh_crs)
182 call this%gs_crs%init(this%dm_crs)
183 call this%e_crs%init(this%dm_crs,
'work crs')
184 call this%c_crs%init(this%gs_crs)
186 call this%Xh_mg%init(
gll, lx_mid, lx_mid, lx_mid)
187 call this%dm_mg%init(msh, this%Xh_mg)
188 call this%gs_mg%init(this%dm_mg)
189 call this%e_mg%init(this%dm_mg,
'work midl')
190 call this%c_mg%init(this%gs_mg)
193 call ax_helm_factory(this%ax, full_formulation = .false.)
196 call precon_factory(this%pc_crs,
'jacobi')
198 call this%bc_crs%init_base(this%c_crs)
199 call this%bc_mg%init_base(this%c_mg)
200 call this%bc_reg%init_base(coef)
201 if (bclst%size() .gt. 0)
then
202 do i = 1, bclst%size()
204 call this%bc_reg%mark_facets(bc_i%marked_facet)
206 call this%bc_crs%mark_facets(bc_i%marked_facet)
208 call this%bc_mg%mark_facets(bc_i%marked_facet)
211 call this%bc_reg%finalize()
212 call this%bc_crs%finalize()
213 call this%bc_mg%finalize()
215 call this%bclst_reg%init()
216 call this%bclst_crs%init()
217 call this%bclst_mg%init()
219 call this%bclst_reg%append(this%bc_reg)
220 call this%bclst_crs%append(this%bc_crs)
221 call this%bclst_mg%append(this%bc_mg)
223 call this%schwarz%init(xh, dof, gs_h, this%bclst_reg, msh)
224 call this%schwarz_mg%init(this%Xh_mg, this%dm_mg, this%gs_mg,&
227 call this%interp_fine_mid%init(xh, this%Xh_mg)
228 call this%interp_mid_crs%init(this%Xh_mg, this%Xh_crs)
230 call hsmg_fill_grid(dof, gs_h, xh, coef, this%bclst_reg, this%schwarz, &
231 this%e, this%grids, 3)
232 call hsmg_fill_grid(this%dm_mg, this%gs_mg, this%Xh_mg, this%c_mg, &
233 this%bclst_mg, this%schwarz_mg, this%e_mg, &
236 this%c_crs, this%bclst_crs, this%schwarz_crs, &
237 this%e_crs, this%grids, 1)
245 select type (pc => this%pc_crs)
247 call pc%init(this%c_crs, this%dm_crs, this%gs_crs)
249 call pc%init(this%c_crs, this%dm_crs, this%gs_crs)
251 call pc%init(this%c_crs, this%dm_crs, this%gs_crs)
258 if (
present(crs_pctype))
then
259 if (trim(crs_pctype) .eq.
'tamg')
then
261 call neko_error(
'Tree-amg only supported for CPU')
264 allocate(this%amg_solver)
266 call this%amg_solver%init(this%ax, this%grids(1)%e%Xh, &
267 this%grids(1)%coef, this%msh, this%grids(1)%gs_h, 4, &
268 this%grids(1)%bclst, 1)
270 call krylov_solver_factory(this%crs_solver, &
275 call krylov_solver_factory(this%crs_solver, &
276 this%dm_crs%size(),
'cg',
ksp_max_iter, m = this%pc_crs)
367 integer,
intent(in) :: n
368 class(
hsmg_t),
intent(inout) :: this
369 real(kind=
rp),
dimension(n),
intent(inout) :: z
370 real(kind=
rp),
dimension(n),
intent(inout) :: r
371 type(c_ptr) :: z_d, r_d
373 integer :: thrdid, nthrds
381 call this%bclst_reg%apply_scalar(r, n)
385 call device_col2(this%r_d, this%grids(3)%coef%mult_d, &
386 this%grids(3)%dof%size())
388 call this%interp_fine_mid%map(this%e%x, this%r, &
389 this%msh%nelv, this%grids(2)%Xh)
390 call this%grids(2)%gs_h%op(this%e%x, &
391 this%grids(2)%dof%size(), gs_op_add, this%gs_event)
394 call this%bclst_reg%apply_scalar(r, n)
395 call device_copy(this%w_d, this%e%x_d, this%grids(2)%dof%size())
396 call this%bclst_mg%apply_scalar(this%w, this%grids(2)%dof%size())
398 call device_col2(this%w_d, this%grids(2)%coef%mult_d, &
399 this%grids(2)%dof%size())
401 call this%interp_mid_crs%map(this%wf%x, this%w, this%msh%nelv, &
404 call device_copy(this%w_d, this%e%x_d, this%grids(2)%dof%size())
405 call this%bclst_mg%apply_scalar(this%w, this%grids(2)%dof%size())
414 if (thrdid .eq. 0)
then
416 call this%grids(3)%schwarz%compute(z, this%r)
417 call this%grids(2)%schwarz%compute(this%grids(2)%e%x, this%w)
420 if (nthrds .eq. 1 .or. thrdid .eq. 1)
then
422 call this%grids(1)%gs_h%op(this%wf%x, &
423 this%grids(1)%dof%size(), gs_op_add, this%gs_event)
425 call this%grids(1)%bclst%apply_scalar(this%wf%x, &
426 this%grids(1)%dof%size())
428 crs_info = this%crs_solver%solve(this%Ax, this%grids(1)%e, &
430 this%grids(1)%dof%size(), &
431 this%grids(1)%coef, &
432 this%grids(1)%bclst, &
433 this%grids(1)%gs_h, this%niter)
435 call this%grids(1)%bclst%apply_scalar(this%grids(1)%e%x,&
436 this%grids(1)%dof%size())
441 call this%interp_mid_crs%map(this%w, this%grids(1)%e%x, &
442 this%msh%nelv, this%grids(2)%Xh)
443 call device_add2(this%grids(2)%e%x_d, this%w_d, this%grids(2)%dof%size())
445 call this%interp_fine_mid%map(this%w, this%grids(2)%e%x, &
446 this%msh%nelv, this%grids(3)%Xh)
447 call device_add2(z_d, this%w_d, this%grids(3)%dof%size())
448 call this%grids(3)%gs_h%op(z, this%grids(3)%dof%size(), &
449 gs_op_add, this%gs_event)
452 this%grids(3)%dof%size())
455 call copy(this%r, r, n)
458 call this%grids(3)%schwarz%compute(z, this%r)
460 call col2(this%r, this%grids(3)%coef%mult, &
461 this%grids(3)%dof%size())
463 call this%interp_fine_mid%map(this%w, this%r, &
464 this%msh%nelv, this%grids(2)%Xh)
465 call this%grids(2)%gs_h%op(this%w, this%grids(2)%dof%size(), gs_op_add)
467 call this%grids(2)%schwarz%compute(this%grids(2)%e%x, this%w)
468 call col2(this%w, this%grids(2)%coef%mult, this%grids(2)%dof%size())
470 call this%interp_mid_crs%map(this%r, this%w, &
471 this%msh%nelv, this%grids(1)%Xh)
474 call this%grids(1)%gs_h%op(this%r, this%grids(1)%dof%size(), gs_op_add)
475 call this%grids(1)%bclst%apply(this%r, this%grids(1)%dof%size())
478 if (
allocated(this%amg_solver))
then
479 call this%amg_solver%solve(this%grids(1)%e%x, this%r, &
480 this%grids(1)%dof%size())
482 crs_info = this%crs_solver%solve(this%Ax, this%grids(1)%e, this%r, &
483 this%grids(1)%dof%size(), &
484 this%grids(1)%coef, &
485 this%grids(1)%bclst, &
486 this%grids(1)%gs_h, this%niter)
490 call this%grids(1)%bclst%apply_scalar(this%grids(1)%e%x, &
491 this%grids(1)%dof%size())
494 call this%interp_mid_crs%map(this%w, this%grids(1)%e%x, &
495 this%msh%nelv, this%grids(2)%Xh)
496 call add2(this%grids(2)%e%x, this%w, this%grids(2)%dof%size())
498 call this%interp_fine_mid%map(this%w, this%grids(2)%e%x, &
499 this%msh%nelv, this%grids(3)%Xh)
500 call add2(z, this%w, this%grids(3)%dof%size())
501 call this%grids(3)%gs_h%op(z, this%grids(3)%dof%size(), gs_op_add)
502 call col2(z, this%grids(3)%coef%mult, this%grids(3)%dof%size())