27 use,
intrinsic :: iso_fortran_env
44 integer,
parameter :: &
57 real(real64),
public :: threshold
58 real(real64) :: relax_factor
60 integer,
public :: maxcycles = 0
63 integer :: restriction_method
64 integer :: relaxation_method
71 type(mg_solver_t),
intent(out) :: this
72 type(namespace_t),
intent(in) :: namespace
73 class(space_t),
intent(in) :: space
74 type(mesh_t),
intent(inout) :: mesh
75 real(real64),
intent(in) :: thr
89 call parse_variable(namespace,
'MultigridPresmoothingSteps', 1, this%presteps)
99 call parse_variable(namespace,
'MultigridPostsmoothingSteps', 4, this%poststeps)
109 call parse_variable(namespace,
'MultigridMaxCycles', 50, this%maxcycles)
122 call parse_variable(namespace,
'MultigridRestrictionMethod', 2, this%restriction_method)
140 if (mesh%use_curvilinear)
then
143 call parse_variable(namespace,
'MultigridRelaxationMethod', gauss_seidel, this%relaxation_method)
161 call parse_variable(namespace,
'MultigridRelaxationFactor', 0.6666_real64, this%relax_factor)
178 real(real64),
contiguous,
intent(inout) :: sol(:)
179 real(real64),
contiguous,
intent(in) :: rhs(:)
182 real(real64) :: resnorm
183 real(real64),
allocatable :: residue(:), coarse_residue(:), correction(:), coarse_correction(:)
187 safe_allocate(residue(1:der%mesh%np_part))
189 if (
associated(der%coarser))
then
190 assert(
associated(op%coarser))
192 safe_allocate(correction(1:der%mesh%np_part))
193 safe_allocate(coarse_residue(1:der%coarser%mesh%np_part))
194 safe_allocate(coarse_correction(1:der%coarser%mesh%np_part))
197 message(1) =
"Multigrid restriction"
204 call dmultigrid_fine2coarse(der%to_coarser, der, der%coarser%mesh, residue, coarse_residue, this%restriction_method)
206 coarse_correction =
m_zero
210 message(1) =
"Multigrid prolongation"
218 safe_deallocate_a(correction)
219 safe_deallocate_a(coarse_residue)
220 safe_deallocate_a(coarse_correction)
222 call multigrid_relax(this, der%mesh, der, op, sol, rhs, this%poststeps)
227 do iter = 1, this%maxcycles
229 call multigrid_relax(this, der%mesh, der, op, sol, rhs, this%presteps + this%poststeps)
233 resnorm =
dmf_nrm2(der%mesh, residue)
234 if (resnorm < this%threshold)
exit
239 write(
message(1),
'(a,i4,a)')
"Multigrid coarsest grid solver converged in ", iter,
" iterations."
240 write(
message(2),
'(a,es18.6)')
"Residue norm is ", resnorm
246 safe_deallocate_a(residue)
256 do ip = 1, der%mesh%np
257 residue(ip) = rhs(ip) - residue(ip)
269 type(
mesh_t),
intent(in) :: mesh
272 real(real64),
contiguous,
intent(inout) :: sol(:)
273 real(real64),
contiguous,
intent(in) :: rhs(:)
274 integer,
intent(in) :: steps
278 real(real64) :: point, factor
279 real(real64),
allocatable :: op_sol(:), diag(:)
284 select case (this%relaxation_method)
292 if (mesh%parallel_in_domains)
then
299 factor = -
m_one/op%w(op%stencil%center, 1)*this%relax_factor
301 op%ri(1, 1), op%rimap_inv(1), op%rimap_inv(2), factor, sol(1), rhs(1))
305 point = sum(op%w(1:nn, ip)*sol(op%index(1:nn, ip)))
306 sol(ip) = sol(ip) - this%relax_factor/op%w(op%stencil%center, ip)*(point-rhs(ip))
315 safe_allocate(op_sol(1:mesh%np))
316 safe_allocate(diag(1:mesh%np))
321 diag(ip) = this%relax_factor/diag(ip)
328 sol(ip) = sol(ip) - diag(ip)*(op_sol(ip) - rhs(ip))
332 safe_deallocate_a(diag)
333 safe_deallocate_a(op_sol)
constant times a vector plus a vector
subroutine get_residual()
Module implementing boundary conditions in Octopus.
subroutine, public dpar_vec_ghost_update(pv, v_local)
Updates ghost points of every node.
type(debug_t), save, public debug
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
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_info(no_lines, iunit, verbose_limit, stress, 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 dmultigrid_fine2coarse(tt, fine_der, coarse_mesh, f_fine, f_coarse, method_p)
subroutine, public dmultigrid_coarse2fine(tt, coarse_der, fine_mesh, f_coarse, f_fine, order, set_bc)
This modules provides the routines for solving Ax=b using the V-shaped multigrid method.
integer, parameter gauss_jacobi
recursive subroutine, public multigrid_solver_cycle(this, der, op, sol, rhs)
Performs one cycle of a V-shaped multigrid solver.
subroutine, public multigrid_solver_init(this, namespace, space, mesh, thr)
subroutine multigrid_relax(this, mesh, der, op, sol, rhs, steps)
Given a nonlocal operator op, perform the relaxation operator.
This module defines non-local operators.
subroutine, public dnl_operator_operate_diag(op, fo)
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