190       crs_monitor, crs_tamg_lvls, crs_tamg_itrs, crs_tamg_cheby_degree)
 
  191    class(
hsmg_t), 
intent(inout), 
target :: this
 
  192    type(
coef_t), 
intent(in), 
target :: coef
 
  193    type(
bc_list_t), 
intent(inout), 
target :: bclst
 
  194    character(len=:), 
intent(inout), 
allocatable :: crs_solver, crs_pc
 
  195    logical, 
intent(inout) :: crs_monitor
 
  196    integer, 
intent(in) :: crs_tamg_lvls, crs_tamg_itrs, crs_tamg_cheby_degree
 
  198    integer :: lx_crs, lx_mid
 
  199    class(
bc_t), 
pointer :: bc_i
 
  201    character(len=LOG_SIZE) :: log_buf
 
  207    if (coef%Xh%lx .lt. 5) 
then 
  208       lx_mid = 
max(coef%Xh%lx-1,3)
 
  210       if (coef%Xh%lx .le. 2) 
then 
  211          call neko_error(
'Polynomial order < 2 not supported for hsmg precon')
 
  220    if (this%nlvls .lt. 1e1) 
then 
  221       write(log_buf, 
'(A,I1,A)') 
'HSMG hierarchy      : ', &
 
  222            this%nlvls, 
' levels' 
  223    else if (this%nlvls .lt. 1e2) 
then 
  224       write(log_buf, 
'(A,I2,A)') 
'HSMG hierarchy      : ', &
 
  225            this%nlvls, 
' levels' 
  226    else if (this%nlvls .lt. 1e3) 
then 
  227       write(log_buf, 
'(A,I3,A)') 
'HSMG hierarchy      : ', this%nlvls, &
 
  230       write(log_buf, 
'(A,I6,A)') 
'HSMG hierarchy      : ', this%nlvls, &
 
  234    if (trim(crs_solver) .ne. 
'tamg' .or. trim(crs_solver) .eq. 
'cheby') 
then 
  235       call neko_log%message(
'Coarse grid solver  : (' // trim(crs_solver) // &
 
  236            ', ' // trim(crs_pc) // 
')')
 
  238       if (this%niter .lt. 1e1) 
then 
  239          write(log_buf, 
'(A,I1)') 
'Coarse grid iters.  : ', this%niter
 
  240       else if (this%niter .lt. 1e2) 
then 
  241          write(log_buf, 
'(A,I2)') 
'Coarse grid iters.  : ', this%niter
 
  242       else if (this%niter .lt. 1e3) 
then 
  243          write(log_buf, 
'(A,I3)') 
'Coarse grid iters.  : ', this%niter
 
  244       else if (this%niter .lt. 1e4) 
then 
  245          write(log_buf, 
'(A,I4)') 
'Coarse grid iters.  : ', this%niter
 
  247          write(log_buf, 
'(A,I6)') 
'Coarse grid iters.  : ', this%niter
 
  252       call neko_log%message(
'Coarse grid solver  : ' // trim(crs_solver) )
 
  256    allocate(this%grids(this%nlvls))
 
  257    allocate(this%w(coef%dof%size()))
 
  258    allocate(this%r(coef%dof%size()))
 
  262    call coef%msh%all_deformed()
 
  265    call this%e%init(coef%dof, 
'work array')
 
  266    call this%wf%init(coef%dof, 
'work 2')
 
  268    call this%Xh_crs%init(
gll, lx_crs, lx_crs, lx_crs)
 
  269    call this%dm_crs%init(coef%msh, this%Xh_crs)
 
  270    call this%gs_crs%init(this%dm_crs)
 
  271    call this%e_crs%init(this%dm_crs, 
'work crs')
 
  272    call this%c_crs%init(this%gs_crs)
 
  274    call this%Xh_mg%init(
gll, lx_mid, lx_mid, lx_mid)
 
  275    call this%dm_mg%init(coef%msh, this%Xh_mg)
 
  276    call this%gs_mg%init(this%dm_mg)
 
  277    call this%e_mg%init(this%dm_mg, 
'work midl')
 
  278    call this%c_mg%init(this%gs_mg)
 
  281    call ax_helm_factory(this%ax, full_formulation = .false.)
 
  283    call this%bc_crs%init_base(this%c_crs)
 
  284    call this%bc_mg%init_base(this%c_mg)
 
  285    call this%bc_reg%init_base(coef)
 
  286    if (bclst%size() .gt. 0) 
then 
  287       do i = 1, bclst%size()
 
  289          call this%bc_reg%mark_facets(bc_i%marked_facet)
 
  291          call this%bc_crs%mark_facets(bc_i%marked_facet)
 
  293          call this%bc_mg%mark_facets(bc_i%marked_facet)
 
  296    call this%bc_reg%finalize()
 
  297    call this%bc_crs%finalize()
 
  298    call this%bc_mg%finalize()
 
  300    call this%bclst_reg%init()
 
  301    call this%bclst_crs%init()
 
  302    call this%bclst_mg%init()
 
  304    call this%bclst_reg%append(this%bc_reg)
 
  305    call this%bclst_crs%append(this%bc_crs)
 
  306    call this%bclst_mg%append(this%bc_mg)
 
  308    call this%schwarz%init(coef%Xh, coef%dof, coef%gs_h, &
 
  309         this%bclst_reg, coef%msh)
 
  310    call this%schwarz_mg%init(this%Xh_mg, this%dm_mg, this%gs_mg,&
 
  311         this%bclst_mg, coef%msh)
 
  313    call this%interp_fine_mid%init(coef%Xh, this%Xh_mg)
 
  314    call this%interp_mid_crs%init(this%Xh_mg, this%Xh_crs)
 
  317         this%bclst_reg, this%schwarz, this%e, this%grids, 3)
 
  318    call hsmg_fill_grid(this%dm_mg, this%gs_mg, this%Xh_mg, this%c_mg, &
 
  319         this%bclst_mg, this%schwarz_mg, this%e_mg, &
 
  322         this%c_crs, this%bclst_crs, this%schwarz_crs, &
 
  323         this%e_crs, this%grids, 1)
 
  337    if (trim(crs_solver) .eq. 
'tamg') 
then 
  338       allocate(this%amg_solver)
 
  339       call this%amg_solver%init(this%ax, this%grids(1)%e%Xh, &
 
  340            this%grids(1)%coef, this%msh, this%grids(1)%gs_h, crs_tamg_lvls, &
 
  341            this%grids(1)%bclst, crs_tamg_itrs, crs_tamg_cheby_degree)
 
  344       call precon_factory(this%pc_crs, crs_pc)
 
  346       select type (pc => this%pc_crs)
 
  348          call pc%init(this%c_crs, this%dm_crs, this%gs_crs)
 
  350          call pc%init(this%c_crs, this%dm_crs, this%gs_crs)
 
  352          call pc%init(this%c_crs, this%dm_crs, this%gs_crs)
 
  355       call krylov_solver_factory(this%crs_solver, &
 
  357            m = this%pc_crs, monitor = crs_monitor)
 
 
  476    integer, 
intent(in) :: n
 
  477    class(
hsmg_t), 
intent(inout) :: this
 
  478    real(kind=
rp), 
dimension(n), 
intent(inout) :: z
 
  479    real(kind=
rp), 
dimension(n), 
intent(inout) :: r
 
  480    type(c_ptr) :: z_d, r_d
 
  482    integer :: thrdid, nthrds
 
  490       call this%bclst_reg%apply_scalar(this%r, n)
 
  494       call device_col2(this%r_d, this%grids(3)%coef%mult_d, &
 
  495            this%grids(3)%dof%size())
 
  497       call this%interp_fine_mid%map(this%e%x, this%r, &
 
  498            this%msh%nelv, this%grids(2)%Xh)
 
  499       call this%grids(2)%gs_h%op(this%e%x, &
 
  500            this%grids(2)%dof%size(), gs_op_add, this%gs_event)
 
  504       call this%bclst_reg%apply_scalar(this%r, n)
 
  505       call device_copy(this%w_d, this%e%x_d, this%grids(2)%dof%size())
 
  506       call this%bclst_mg%apply_scalar(this%w, this%grids(2)%dof%size())
 
  508       call device_col2(this%w_d, this%grids(2)%coef%mult_d, &
 
  509            this%grids(2)%dof%size())
 
  511       call this%interp_mid_crs%map(this%wf%x, this%w, this%msh%nelv, &
 
  514       call device_copy(this%w_d, this%e%x_d, this%grids(2)%dof%size())
 
  515       call this%bclst_mg%apply_scalar(this%w, this%grids(2)%dof%size())
 
  524       if (thrdid .eq. 0) 
then 
  526          call this%grids(3)%schwarz%compute(z, this%r)
 
  527          call this%grids(2)%schwarz%compute(this%grids(2)%e%x, this%w)
 
  530       if (nthrds .eq. 1 .or. thrdid .eq. 1) 
then 
  532          call this%grids(1)%gs_h%op(this%wf%x, &
 
  533               this%grids(1)%dof%size(), gs_op_add, this%gs_event)
 
  535          call this%grids(1)%bclst%apply_scalar(this%wf%x, &
 
  536               this%grids(1)%dof%size())
 
  538          if (
allocated(this%amg_solver)) 
then 
  539             call this%amg_solver%solve(this%grids(1)%e%x, this%wf%x, &
 
  540                  this%grids(1)%dof%size())
 
  542             crs_info = this%crs_solver%solve(this%Ax, this%grids(1)%e, &
 
  544                  this%grids(1)%dof%size(), &
 
  545                  this%grids(1)%coef, &
 
  546                  this%grids(1)%bclst, &
 
  547                  this%grids(1)%gs_h, this%niter)
 
  550          call this%grids(1)%bclst%apply_scalar(this%grids(1)%e%x,&
 
  551               this%grids(1)%dof%size())
 
  556       call this%interp_mid_crs%map(this%w, this%grids(1)%e%x, &
 
  557            this%msh%nelv, this%grids(2)%Xh)
 
  558       call device_add2(this%grids(2)%e%x_d, this%w_d, this%grids(2)%dof%size())
 
  560       call this%interp_fine_mid%map(this%w, this%grids(2)%e%x, &
 
  561            this%msh%nelv, this%grids(3)%Xh)
 
  562       call device_add2(z_d, this%w_d, this%grids(3)%dof%size())
 
  563       call this%grids(3)%gs_h%op(z, this%grids(3)%dof%size(), &
 
  564            gs_op_add, this%gs_event)
 
  567            this%grids(3)%dof%size())
 
  570       call copy(this%r, r, n)
 
  573       call this%grids(3)%schwarz%compute(z, this%r)
 
  575       call col2(this%r, this%grids(3)%coef%mult, &
 
  576            this%grids(3)%dof%size())
 
  578       call this%interp_fine_mid%map(this%w, this%r, &
 
  579            this%msh%nelv, this%grids(2)%Xh)
 
  580       call this%grids(2)%gs_h%op(this%w, this%grids(2)%dof%size(), gs_op_add)
 
  582       call this%grids(2)%schwarz%compute(this%grids(2)%e%x, this%w)
 
  583       call col2(this%w, this%grids(2)%coef%mult, this%grids(2)%dof%size())
 
  585       call this%interp_mid_crs%map(this%r, this%w, &
 
  586            this%msh%nelv, this%grids(1)%Xh)
 
  589       call this%grids(1)%gs_h%op(this%r, this%grids(1)%dof%size(), gs_op_add)
 
  590       call this%grids(1)%bclst%apply(this%r, this%grids(1)%dof%size())
 
  593       if (
allocated(this%amg_solver)) 
then 
  594          call this%amg_solver%solve(this%grids(1)%e%x, this%r, &
 
  595               this%grids(1)%dof%size())
 
  597          crs_info = this%crs_solver%solve(this%Ax, this%grids(1)%e, this%r, &
 
  598               this%grids(1)%dof%size(), &
 
  599               this%grids(1)%coef, &
 
  600               this%grids(1)%bclst, &
 
  601               this%grids(1)%gs_h, this%niter)
 
  605       call this%grids(1)%bclst%apply_scalar(this%grids(1)%e%x, &
 
  606            this%grids(1)%dof%size())
 
  609       call this%interp_mid_crs%map(this%w, this%grids(1)%e%x, &
 
  610            this%msh%nelv, this%grids(2)%Xh)
 
  611       call add2(this%grids(2)%e%x, this%w, this%grids(2)%dof%size())
 
  613       call this%interp_fine_mid%map(this%w, this%grids(2)%e%x, &
 
  614            this%msh%nelv, this%grids(3)%Xh)
 
  615       call add2(z, this%w, this%grids(3)%dof%size())
 
  616       call this%grids(3)%gs_h%op(z, this%grids(3)%dof%size(), gs_op_add)
 
  617       call col2(z, this%grids(3)%coef%mult, this%grids(3)%dof%size())