Octopus
poisson_cg.F90
Go to the documentation of this file.
1!! Cropyright (C) 2004-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
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
22 use debug_oct_m
24 use global_oct_m
25 use iso_c_binding, only: c_loc
26 use, intrinsic :: iso_fortran_env
29 use mesh_oct_m
36
37 implicit none
38
39 private
40 public :: &
45
46 real(real64), public :: threshold
47 integer, public :: maxiter
48
49contains
50
51
52 ! ---------------------------------------------------------
53 subroutine poisson_cg_init(thr, itr)
54 integer, intent(in) :: itr
55 real(real64), intent(in) :: thr
56
57 push_sub(poisson_cg_init)
58 threshold = thr
59 maxiter = itr
60 pop_sub(poisson_cg_init)
61 end subroutine poisson_cg_init
62
63
64 ! ---------------------------------------------------------
65 subroutine poisson_cg_end
66
67 end subroutine poisson_cg_end
68
69
70 ! ---------------------------------------------------------
71 subroutine poisson_cg1(namespace, der, corrector, pot, rho)
72 type(namespace_t), intent(in) :: namespace
73 type(derivatives_t), target, intent(in) :: der
74 type(poisson_corr_t), intent(in) :: corrector
75 real(real64), contiguous, intent(inout) :: pot(:)
76 real(real64), intent(in) :: rho(:)
77
78 integer :: iter, ip
79 real(real64) :: res
80 real(real64), allocatable :: wk(:), lwk(:), rhs(:), sol(:)
81
82 push_sub(poisson_cg1)
83
84 safe_allocate( wk(1:der%mesh%np_part))
85 safe_allocate(lwk(1:der%mesh%np_part))
86 safe_allocate(rhs(1:der%mesh%np_part))
87 safe_allocate(sol(1:der%mesh%np_part))
88
89 ! build initial guess for the potential
90 wk(1:der%mesh%np) = pot(1:der%mesh%np)
91 if (der%periodic_dim > 0) then
92 call dderivatives_lapl(der, wk, lwk, ghost_update = .true.)
93 else
94 call poisson_boundary_conditions(corrector, der%mesh, rho, wk)
95 call dderivatives_lapl(der, wk, lwk, ghost_update = .true., set_bc = .false.)
96 end if
97
98 ! Solving -\Delta = rhs, as CG require SDP operator
99 !$omp parallel do
100 do ip = 1, der%mesh%np
101 rhs(ip) = (m_four*m_pi*rho(ip) + lwk(ip))
102 end do
103 !$omp end parallel do
104 if (der%periodic_dim > 0) call dmf_remove_average(der%mesh, rhs)
105 safe_deallocate_a(wk)
106 safe_deallocate_a(lwk) ! they are no longer needed
107
108 der_pointer => der
109 mesh_pointer => der%mesh
110 mesh_aux => der%mesh
111 call lalg_copy(der%mesh%np, rhs, sol)
112 iter = maxiter
113 if (der%periodic_dim > 0) then
114 call dconjugate_gradients(der%mesh%np, sol, rhs, dlaplacian_op, internal_dotp, iter, res, &
115 threshold, userdata=[c_loc(der)], nullspace=dmf_remove_average_aux)
116 else
117 call dconjugate_gradients(der%mesh%np, sol, rhs, dlaplacian_op, internal_dotp, iter, res, threshold, userdata=[c_loc(der)])
118 end if
119 if (res >= threshold) then
120 message(1) = 'Conjugate-gradients Poisson solver did not converge.'
121 write(message(2), '(a,i8)') ' Iter = ',iter
122 write(message(3), '(a,e14.6)') ' Res = ', res
123 call messages_warning(3, namespace=namespace)
124 end if
125 nullify(der_pointer, mesh_pointer)
126 call lalg_axpy(der%mesh%np, m_one, sol, pot)
127
128 safe_deallocate_a(rhs)
129 safe_deallocate_a(sol)
130 pop_sub(poisson_cg1)
131 end subroutine poisson_cg1
132
133
134 ! ---------------------------------------------------------
135 subroutine poisson_cg2(namespace, der, pot, rho)
136 type(namespace_t), intent(in) :: namespace
137 type(derivatives_t), target, intent(in) :: der
138 real(real64), contiguous, intent(inout) :: pot(:)
139 real(real64), intent(in) :: rho(:)
140
141 integer :: iter, ip
142 real(real64), allocatable :: potc(:), rhs(:)
143 real(real64) :: res
144
145 push_sub(poisson_cg2)
146
147 iter = maxiter
149 mesh_pointer => der%mesh
150
151 safe_allocate(rhs(1:der%mesh%np))
152 safe_allocate(potc(1:der%mesh%np_part))
153
154 ! Solving -\Delta = rhs, as CG require SDP operator
155 do ip = 1, der%mesh%np
156 rhs(ip) = 4.0_real64*m_pi*rho(ip)
157 end do
158 call lalg_copy(der%mesh%np, pot, potc)
159
160 call dconjugate_gradients(der%mesh%np, potc, rhs, dlaplacian_op, internal_dotp, iter, res, threshold, userdata=[c_loc(der)])
161
162 if (res >= threshold) then
163 message(1) = 'Conjugate-gradients Poisson solver did not converge.'
164 write(message(2), '(a,i8)') ' Iter = ', iter
165 write(message(3), '(a,e14.6)') ' Res = ', res
166 call messages_warning(3, namespace=namespace)
167 end if
168
169 call lalg_copy(der%mesh%np, potc, pot)
170
171 nullify(der_pointer, mesh_pointer)
172
173 safe_deallocate_a(rhs)
174 safe_deallocate_a(potc)
175
176 pop_sub(poisson_cg2)
177 end subroutine poisson_cg2
178
179end module poisson_cg_oct_m
180
181!! Local Variables:
182!! mode: f90
183!! coding: utf-8
184!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:173
Copies a vector x, to a vector y.
Definition: lalg_basic.F90:188
This module calculates the derivatives (gradients, Laplacians, etc.) of a 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_four
Definition: global.F90:204
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:198
real(real64), parameter, public m_one
Definition: global.F90:201
Computes and , suitable as an operator callback for iterative solvers (CG, QMR, etc....
subroutine, public dlaplacian_op(x, hx, userdata)
Computes the negative Laplacian operator action: .
This module defines various routines, operating on mesh functions.
class(mesh_t), pointer, public mesh_aux
Globally-scoped pointer to the mesh instance.
subroutine, public dmf_remove_average(mesh, ff, reduce)
Remove the average value of a mesh function.
subroutine, public dmf_remove_average_aux(f)
Interface for nullspace removal in linear solvers.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public poisson_cg2(namespace, der, pot, rho)
Definition: poisson_cg.F90:231
subroutine, public poisson_cg1(namespace, der, corrector, pot, rho)
Definition: poisson_cg.F90:167
subroutine, public poisson_cg_init(thr, itr)
Definition: poisson_cg.F90:149
subroutine, public poisson_cg_end
Definition: poisson_cg.F90:161
real(real64) function, public internal_dotp(xx, yy)
subroutine, public poisson_boundary_conditions(this, mesh, rho, pot)
type(mesh_t), pointer, public mesh_pointer
type(derivatives_t), pointer, public der_pointer
This module is intended to contain "only mathematical" functions and procedures.
Definition: solvers.F90:117
int true(void)