85 subroutine tamg_mg_init(this, ax, Xh, coef, msh, gs_h, nlvls_in, blst, max_iter)
87 class(
ax_t),
target,
intent(in) :: ax
88 type(
space_t),
target,
intent(in) :: Xh
89 type(
coef_t),
target,
intent(in) :: coef
90 type(
mesh_t),
target,
intent(in) :: msh
91 type(
gs_t),
target,
intent(in) :: gs_h
92 type(
bc_list_t),
target,
intent(in) :: blst
93 integer,
intent(in) :: nlvls_in
94 integer,
intent(in) :: max_iter
95 integer :: nlvls, lvl, n, cheby_degree, env_len, mlvl, target_num_aggs
96 integer,
allocatable :: agg_nhbr(:,:), asdf(:,:)
97 character(len=255) :: env_cheby_degree, env_mlvl
98 character(len=LOG_SIZE) :: log_buf
102 call get_environment_variable(
"NEKO_TAMG_MAX_LVL", &
104 if (env_len .eq. 0)
then
108 read(env_mlvl(1:env_len), *) mlvl
112 write(log_buf,
'(A28,I2,A8)')
'Creating AMG hierarchy with', nlvls,
'levels.'
116 call this%amg%init(ax, xh, coef, msh, gs_h, nlvls, blst)
122 allocate( agg_nhbr, source=msh%facet_neigh )
124 target_num_aggs = this%amg%lvl(mlvl-1)%nnodes / 8
126 if ( target_num_aggs .lt. 4 )
then
127 call neko_error(
"TAMG: Too many levels. Not enough DOFs for coarsest grid.")
133 deallocate( agg_nhbr )
138 this%max_iter = max_iter
140 this%nlvls = this%amg%nlvls
141 if (this%nlvls .gt. this%amg%nlvls)
then
142 call neko_error(
"Requested number multigrid levels is greater than the initialized AMG levels")
145 call get_environment_variable(
"NEKO_TAMG_CHEBY_DEGREE", &
146 env_cheby_degree, env_len)
147 if (env_len .eq. 0)
then
150 read(env_cheby_degree(1:env_len), *) cheby_degree
153 allocate(this%smoo(0:(nlvls)))
155 n = this%amg%lvl(lvl+1)%fine_lvl_dofs
156 call this%smoo(lvl)%init(n ,lvl, cheby_degree)
177 integer,
intent(in) :: n
179 real(kind=
rp),
dimension(n),
intent(inout) :: z
180 real(kind=
rp),
dimension(n),
intent(inout) :: r
181 integer :: iter, max_iter
183 max_iter = this%max_iter
189 do iter = 1, max_iter
202 integer,
intent(in) :: n
203 real(kind=
rp),
intent(inout) :: x(n)
204 real(kind=
rp),
intent(inout) :: b(n)
207 integer,
intent(in) :: lvl
208 real(kind=
rp) :: r(n)
209 real(kind=
rp) :: rc(n)
210 real(kind=
rp) :: tmp(n)
211 integer :: iter, num_iter
219 max_lvl = mgstuff%nlvls-1
226 call mgstuff%smoo(lvl)%solve(x,b, n, amg)
228 if (lvl .eq. max_lvl)
then
243 call amg%interp_f2c(rc, r, lvl+1)
249 call tamg_mg_cycle(tmp, rc, amg%lvl(lvl+1)%nnodes, lvl+1, amg, mgstuff)
254 call amg%interp_c2f(r, tmp, lvl+1)
267 call mgstuff%smoo(lvl)%solve(x,b, n, amg)
286 integer,
intent(in) :: n
287 real(kind=
rp),
intent(inout) :: r(n)
288 real(kind=
rp),
intent(inout) :: x(n)
289 real(kind=
rp),
intent(inout) :: b(n)
291 integer,
intent(in) :: lvl
295 call amg%matvec(r, x, lvl)
307 integer,
intent(in) :: n
308 real(kind=
rp),
intent(inout) :: u(n)
310 integer,
intent(in) :: lvl
312 call amg%gs_h%op(u, n, gs_op_add)
314 u(i) = u(i) * amg%coef%mult(i,1,1,1)
319 integer,
intent(in) :: lvl,nagg
320 character(len=LOG_SIZE) :: log_buf
322 write(log_buf,
'(A8,I2,A31)')
'-- level',lvl,
'-- Calling Greedy Aggregation'
324 write(log_buf,
'(A33,I6)')
'Target Aggregates:',nagg
330 integer :: i, j, k, l, nid, n
331 do j = 1, amg%lvl(1)%nnodes
332 do k = 1, amg%lvl(1)%nodes(j)%ndofs
333 nid = amg%lvl(1)%nodes(j)%dofs(k)
334 amg%lvl(1)%map_f2c_dof(nid) = amg%lvl(1)%nodes(j)%gid
337 n =
size(amg%lvl(1)%map_f2c_dof)
340 nid = amg%lvl(l-1)%map_f2c_dof(i)
341 do j = 1, amg%lvl(l)%nnodes
342 do k = 1, amg%lvl(l)%nodes(j)%ndofs
343 if (nid .eq. amg%lvl(l)%nodes(j)%dofs(k))
then
344 amg%lvl(l)%map_f2c_dof(i) = amg%lvl(l)%nodes(j)%gid
Defines a Matrix-vector product.
type(log_t), public neko_log
Global log stream.
integer, parameter, public log_size
subroutine, public add2(a, b, n)
Vector addition .
integer, parameter, public rp
Global precision used in computations.
Defines a function space.
Implements an aggregation for TreeAMG hierarchy structure.
subroutine aggregate_end(tamg, lvl_id)
Aggregate all dofs to a single point to form a tree-like structure.
subroutine aggregate_greedy(tamg, lvl_id, max_aggs, facet_neigh, agg_nhbr)
Aggregates dofs based on adjacent dofs.
subroutine aggregate_finest_level(tamg, lx, ly, lz, ne)
Aggregaiton on finest level Aggregates all dofs in an element into a single aggregate.
Implements multigrid using the TreeAMG hierarchy structure. USE:
subroutine calc_resid(r, x, b, amg, lvl, n)
Wrapper function to calculate residyal.
recursive subroutine tamg_mg_cycle(x, b, n, lvl, amg, mgstuff)
Recrsive multigrid cycle for the TreeAMG solver object.
subroutine tamg_mg_init(this, ax, xh, coef, msh, gs_h, nlvls_in, blst, max_iter)
Initialization of the TreeAMG multigrid solver.
subroutine print_preagg_info(lvl, nagg)
subroutine average_duplicates(u, amg, lvl, n)
Wrapper function to gather scatter and average the duplicates.
subroutine fill_lvl_map(amg)
subroutine tamg_mg_solve(this, z, r, n)
Solver function for the TreeAMG solver object.
Implements smoothers for use with TreeAMG matrix vector product.
Implements the base type for TreeAMG hierarchy structure.
subroutine, public tamg_node_init(node, gid, ndofs)
Initialization of a TreeAMG tree node.
subroutine, public tamg_lvl_init(tamg_lvl, lvl, nnodes, ndofs)
Initialization of a TreeAMG level.
Base type for a matrix-vector product providing .
A list of allocatable `bc_t`. Follows the standard interface of lists.
Coefficients defined on a given (mesh, ) tuple. Arrays use indices (i,j,k,e): element e,...
The function space for the SEM solution fields.
Type for a TreeAMG hierarchy.
Type for the TreeAMG solver.
Type for Chebyshev iteration using TreeAMG matvec.