Octopus
poisson_multigrid.F90
Go to the documentation of this file.
1!! Copyright (C) 2005-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch, X. Andrade
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
23 use debug_oct_m
25 use global_oct_m
26 use, intrinsic :: iso_fortran_env
28 use mesh_oct_m
35 use parser_oct_m
38 use space_oct_m
40
41 implicit none
42
43 private
44 public :: &
49
51 private
52
53 type(poisson_corr_t) :: corrector
54 type(multigrid_t) :: mgrid ! multigrid object
55 type(mg_solver_t) :: mg_solver
56 logical :: periodic = .false.
57
58 integer :: multigrid_cycle
59
60 end type poisson_mg_solver_t
61
62contains
63
64 ! ---------------------------------------------------------
65 subroutine poisson_multigrid_init(this, namespace, space, mesh, der, stencil, mc, ml, thr)
66 type(poisson_mg_solver_t), intent(out) :: this
67 type(namespace_t), intent(in) :: namespace
68 class(space_t), intent(in) :: space
69 type(mesh_t), intent(inout) :: mesh
70 type(derivatives_t), intent(in) :: der
71 type(stencil_t), intent(in) :: stencil
72 type(multicomm_t), intent(in) :: mc
73 integer, intent(in) :: ml
74 real(real64), intent(in) :: thr
75
76 integer :: i
77
79
80 this%periodic = space%is_periodic()
81 if (.not. this%periodic) then
82 call poisson_corrections_init(this%corrector, namespace, space, ml, mesh)
83 end if
84
85 call multigrid_init(this%mgrid, namespace, space, mesh, der, stencil, mc)
86
87 ! For the multigrid solver to work, we need to set a pointer from one operator
88 ! to the corresponding one on the coarser grid.
89 do i = 1, this%mgrid%n_levels
90 this%mgrid%level(i - 1)%der%lapl%coarser => this%mgrid%level(i)%der%lapl
91 end do
92
93 call multigrid_solver_init(this%mg_solver, namespace, mesh, thr)
94
95 !%Variable PoissonMultigridCycle
96 !%Type integer
97 !%Section Hamiltonian::Poisson::Multigrid
98 !%Description
99 !% The flavor of multigrid cycle
100 !%Option v_shape 1
101 !% V-shape cycle
102 !%Option w_shape 2
103 !% W-shape cycle
104 !%Option fmg 3
105 !% Full multigrid solver
106 !%End
107 call parse_variable(namespace, 'PoissonMultigridCycle', mg_v_shape, this%multigrid_cycle)
108
110 end subroutine poisson_multigrid_init
111
112
113 ! ---------------------------------------------------------
114 subroutine poisson_multigrid_end(this)
115 type(poisson_mg_solver_t), intent(inout) :: this
117 push_sub(poisson_multigrid_end)
118
119 if (.not. this%periodic) call poisson_corrections_end(this%corrector)
120
121 call multigrid_end(this%mgrid)
122
123 pop_sub(poisson_multigrid_end)
124 end subroutine poisson_multigrid_end
125
126
127 ! ---------------------------------------------------------
129 subroutine poisson_multigrid_solver(this, namespace, der, pot, rho)
130 type(poisson_mg_solver_t), intent(in) :: this
131 type(namespace_t), intent(in) :: namespace
132 type(derivatives_t), intent(in) :: der
133 real(real64), intent(out) :: pot(:)
134 real(real64), contiguous, intent(in) :: rho(:)
135
136 integer :: ip
137 real(real64), allocatable :: vh_correction(:), res(:), cor(:)
138
140
141 safe_allocate(res(1:der%mesh%np_part))
142 safe_allocate(cor(1:der%mesh%np_part))
143 cor = m_zero
144
145 if (this%periodic) then
146 res(1:der%mesh%np) = rho(1:der%mesh%np)
147 call lalg_scal(der%mesh%np, -m_four*m_pi, res)
148 call dmf_remove_average(der%mesh, res)
149 else
150 ! correction for treating boundaries
151 safe_allocate(vh_correction(1:der%mesh%np_part))
152 call correct_rho(this%corrector, der, rho, res, vh_correction)
153 call lalg_scal(der%mesh%np, -m_four*m_pi, res)
154 end if
155
156 select case (this%multigrid_cycle)
158 call multigrid_iterative_solver(this%mg_solver, namespace, this%mgrid%level(0)%der, this%mgrid%level(0)%der%lapl, &
159 cor, res, this%multigrid_cycle)
160 case(mg_fmg)
161 call multigrid_fmg_solver(this%mg_solver, namespace, this%mgrid%level(0)%der, this%mgrid%level(0)%der%lapl, cor, res)
162 case default
163 assert(.false.)
164 end select
165
166 if (this%periodic) then
167 call dmf_remove_average(der%mesh, cor)
168 pot(1:der%mesh%np) = cor(1:der%mesh%np)
169 else
170 do ip = 1, der%mesh%np
171 pot(ip) = cor(ip) + vh_correction(ip)
172 end do
173 safe_deallocate_a(vh_correction)
174 end if
175 safe_deallocate_a(res)
176 safe_deallocate_a(cor)
177
179 end subroutine poisson_multigrid_solver
180
182
183!! Local Variables:
184!! mode: f90
185!! coding: utf-8
186!! End:
scales a vector by a constant
Definition: lalg_basic.F90:159
Module implementing boundary conditions in Octopus.
Definition: boundaries.F90:124
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_four
Definition: global.F90:204
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:198
This module defines various routines, operating on mesh functions.
subroutine, public dmf_remove_average(mesh, ff, reduce)
Remove the average value of a mesh function.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
subroutine, public multigrid_end(mgrid)
Definition: multigrid.F90:516
subroutine, public multigrid_init(mgrid, namespace, space, mesh, der, stencil, mc, nlevels)
Definition: multigrid.F90:187
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.
subroutine, public multigrid_solver_init(this, namespace, mesh, thr)
subroutine, public multigrid_iterative_solver(this, namespace, der, op, sol, rhs, multigrid_shape)
An iterative multigrid solver.
integer, parameter, public mg_fmg
integer, parameter, public mg_v_shape
integer, parameter, public mg_w_shape
subroutine, public poisson_corrections_end(this)
subroutine, public poisson_corrections_init(this, namespace, space, ml, mesh)
subroutine, public correct_rho(this, der, rho, rho_corrected, vh_correction)
subroutine, public poisson_multigrid_solver(this, namespace, der, pot, rho)
A multigrid Poisson solver with corrections at the boundaries.
subroutine, public poisson_multigrid_end(this)
subroutine, public poisson_multigrid_init(this, namespace, space, mesh, der, stencil, mc, ml, thr)
This module defines stencils used in Octopus.
Definition: stencil.F90:137