28 use,
intrinsic :: iso_fortran_env
45 integer,
parameter :: &
61 real(real64),
public :: threshold
62 real(real64) :: relax_factor
64 integer,
public :: maxcycles = 0
67 integer :: restriction_method
68 integer :: relaxation_method
71 integer,
parameter,
public :: &
80 type(mg_solver_t),
intent(out) :: this
81 type(namespace_t),
intent(in) :: namespace
82 class(space_t),
intent(in) :: space
83 type(mesh_t),
intent(inout) :: mesh
84 real(real64),
intent(in) :: thr
98 call parse_variable(namespace,
'MultigridPresmoothingSteps', 1, this%presteps)
108 call parse_variable(namespace,
'MultigridPostsmoothingSteps', 4, this%poststeps)
118 call parse_variable(namespace,
'MultigridMaxCycles', 50, this%maxcycles)
131 call parse_variable(namespace,
'MultigridRestrictionMethod', 2, this%restriction_method)
149 if (mesh%use_curvilinear)
then
152 call parse_variable(namespace,
'MultigridRelaxationMethod', gauss_seidel, this%relaxation_method)
169 call parse_variable(namespace,
'MultigridRelaxationFactor', 0.6666_real64, this%relax_factor)
184 real(real64),
contiguous,
intent(inout) :: sol(:)
185 real(real64),
contiguous,
intent(in) :: rhs(:)
187 real(real64),
allocatable :: residue(:), coarse_residue(:), correction(:), coarse_correction(:)
191 safe_allocate(residue(1:der%mesh%np_part))
193 if (
associated(der%coarser))
then
194 assert(
associated(op%coarser))
196 safe_allocate(correction(1:der%mesh%np_part))
197 safe_allocate(coarse_residue(1:der%coarser%mesh%np_part))
198 safe_allocate(coarse_correction(1:der%coarser%mesh%np_part))
207 message(1) =
"Debug: Multigrid restriction"
210 call dmultigrid_fine2coarse(der%to_coarser, der, der%coarser%mesh, residue, coarse_residue, this%restriction_method)
213 coarse_correction =
m_zero
217 message(1) =
"Debug: Multigrid prolongation"
226 safe_deallocate_a(correction)
227 safe_deallocate_a(coarse_residue)
228 safe_deallocate_a(coarse_correction)
231 call multigrid_relax(this, der%mesh, der, op, sol, rhs, this%poststeps)
239 safe_deallocate_a(residue)
252 real(real64),
contiguous,
intent(inout) :: sol(:)
253 real(real64),
contiguous,
intent(in) :: rhs(:)
255 real(real64),
allocatable :: residue(:), coarse_residue(:), correction(:), coarse_correction(:)
259 safe_allocate(residue(1:der%mesh%np_part))
261 if (
associated(der%coarser))
then
262 assert(
associated(op%coarser))
264 safe_allocate(correction(1:der%mesh%np_part))
265 safe_allocate(coarse_residue(1:der%coarser%mesh%np_part))
266 safe_allocate(coarse_correction(1:der%coarser%mesh%np_part))
275 message(1) =
"Debug: Multigrid restriction"
278 call dmultigrid_fine2coarse(der%to_coarser, der, der%coarser%mesh, residue, coarse_residue, this%restriction_method)
281 coarse_correction =
m_zero
285 message(1) =
"Debug: Multigrid prolongation"
301 message(1) =
"Debug: Multigrid restriction"
304 call dmultigrid_fine2coarse(der%to_coarser, der, der%coarser%mesh, residue, coarse_residue, this%restriction_method)
307 coarse_correction =
m_zero
311 message(1) =
"Debug: Multigrid prolongation"
320 safe_deallocate_a(correction)
321 safe_deallocate_a(coarse_residue)
322 safe_deallocate_a(coarse_correction)
325 call multigrid_relax(this, der%mesh, der, op, sol, rhs, this%poststeps)
333 safe_deallocate_a(residue)
348 real(real64),
contiguous,
intent(inout) :: sol(:)
349 real(real64),
contiguous,
intent(inout) :: rhs(:)
350 integer,
intent(in) :: multigrid_shape
353 real(real64) :: resnorm
354 real(real64),
allocatable :: err(:)
358 safe_allocate(err(1:der%mesh%np))
360 do iter = 1, this%maxcycles
362 select case (multigrid_shape)
375 if (resnorm < this%threshold)
exit
377 write(
message(1),
'(a,i5,a,e13.6)')
"Multigrid: base level: iter ", iter,
" res ", resnorm
382 if (resnorm >= this%threshold)
then
383 message(1) =
'Multigrid Poisson solver did not converge.'
384 write(
message(2),
'(a,e14.6)')
' Abs. norm of the residue = ', resnorm
387 write(
message(1),
'(a,i4,a)')
"Multigrid Poisson solver converged in ", iter,
" iterations."
388 write(
message(2),
'(a,e14.6)')
' Abs. norm of the residue = ', resnorm
392 safe_deallocate_a(err)
407 real(real64),
contiguous,
intent(inout) :: sol(:)
408 real(real64),
contiguous,
intent(inout) :: rhs(:)
410 real(real64),
allocatable :: coarse_solution(:), coarse_rhs(:), residue(:)
414 if (
associated(der%coarser))
then
415 assert(
associated(op%coarser))
417 safe_allocate(coarse_rhs(1:der%coarser%mesh%np_part))
418 safe_allocate(coarse_solution(1:der%coarser%mesh%np_part))
421 message(1) =
"Debug: Full Multigrid restriction"
424 call dmultigrid_fine2coarse(der%to_coarser, der, der%coarser%mesh, rhs, coarse_rhs, this%restriction_method)
428 call multigrid_fmg_solver(this, namespace, der%coarser, op%coarser, coarse_solution, coarse_rhs)
431 message(1) =
"Debug: Full Multigrid prolongation"
440 safe_deallocate_a(coarse_solution)
441 safe_deallocate_a(coarse_rhs)
445 safe_allocate(residue(1:der%mesh%np))
447 safe_deallocate_a(residue)
460 real(real64),
contiguous,
intent(inout) :: sol(:)
461 real(real64),
contiguous,
intent(in) :: rhs(:)
462 real(real64),
contiguous,
intent(inout) :: residue(:)
465 real(real64) :: resnorm
470 do iter = 1, this%maxcycles
475 resnorm =
dmf_nrm2(der%mesh, residue)
476 if (resnorm < this%threshold)
exit
480 write(
message(1),
'(a,i4,a)')
"Debug: Multigrid coarsest grid solver converged in ", iter,
" iterations."
481 write(
message(2),
'(a,es18.6)')
" Residue norm is ", resnorm
492 real(real64),
contiguous,
intent(inout) :: sol(:)
493 real(real64),
contiguous,
intent(in) :: rhs(:)
494 real(real64),
contiguous,
intent(inout) :: residue(:)
501 do ip = 1, der%mesh%np
502 residue(ip) = rhs(ip) - residue(ip)
513 type(
mesh_t),
intent(in) :: mesh
516 real(real64),
contiguous,
intent(inout) :: sol(:)
517 real(real64),
contiguous,
intent(in) :: rhs(:)
518 integer,
intent(in) :: steps
520 integer :: istep, index
521 integer :: ip, nn, is
522 real(real64) :: point, factor
523 real(real64),
allocatable :: op_sol(:), diag(:)
528 select case (this%relaxation_method)
536 if (mesh%parallel_in_domains)
then
543 factor = -
m_one/op%w(op%stencil%center, 1)
545 op%ri(1, 1), op%rimap_inv(1), op%rimap_inv(2), factor, sol(1), rhs(1))
552 point = point + op%w(is, ip)*sol(index)
554 sol(ip) = sol(ip) - (point-rhs(ip))/op%w(op%stencil%center, ip)
563 safe_allocate(op_sol(1:mesh%np))
564 safe_allocate(diag(1:mesh%np))
569 diag(ip) = this%relax_factor/diag(ip)
576 sol(ip) = sol(ip) - diag(ip)*(op_sol(ip) - rhs(ip))
580 safe_deallocate_a(diag)
581 safe_deallocate_a(op_sol)
constant times a vector plus a vector
Module implementing boundary conditions in Octopus.
subroutine, public dpar_vec_ghost_update(pv, v_local)
Updates ghost points of every node.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_perform(op, der, ff, op_ff, ghost_update, set_bc, factor)
apply a nl_operator to a mesh function
subroutine, public dderivatives_lapl(der, ff, op_ff, ghost_update, set_bc, factor)
apply the Laplacian to a mesh function
real(real64), parameter, public m_zero
real(real64), parameter, public m_one
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_warning(no_lines, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
subroutine, public dmultigrid_coarse2fine(tt, coarse_der, fine_mesh, f_coarse, f_fine, set_bc)
subroutine, public dmultigrid_fine2coarse(tt, fine_der, coarse_mesh, f_fine, f_coarse, method_p)
This modules provides the routines for solving Ax=b using the V-shaped multigrid method.
recursive subroutine, public multigrid_fmg_solver(this, namespace, der, op, sol, rhs)
Full multigrid (FMG) solver.
recursive subroutine, public multigrid_solver_v_cycle(this, der, op, sol, rhs)
Performs one cycle of a V-shaped multigrid solver.
recursive subroutine, public multigrid_solver_w_cycle(this, der, op, sol, rhs)
Performs one cycle of a W-shaped multigrid solver.
subroutine multigrid_solver_solve_coarsest(this, der, op, sol, rhs, residue)
Computes the solution on the coarsest grid.
subroutine, public multigrid_iterative_solver(this, namespace, der, op, sol, rhs, multigrid_shape)
An iterative multigrid solver.
integer, parameter weighted_jacobi
subroutine, public multigrid_solver_init(this, namespace, space, mesh, thr)
integer, parameter, public mg_fmg
subroutine get_residual(op, der, sol, rhs, residue)
Computes the residual.
subroutine multigrid_relax(this, mesh, der, op, sol, rhs, steps)
Given a nonlocal operator op, perform the relaxation operator.
integer, parameter, public mg_w_shape
This module defines non-local operators.
subroutine, public dnl_operator_operate_diag(op, fo)
integer pure function, public nl_operator_get_index(op, is, ip)
This module contains interfaces for routines in operate.c.
Some general things and nomenclature:
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
class representing derivatives
Describes mesh distribution to nodes.
data type for non local operators