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, intrinsic :: iso_c_binding, only: c_ptr
26 use, intrinsic :: iso_fortran_env
28 use mesh_oct_m
34
35 implicit none
36
37 private
38 public :: &
43
44 real(real64), public :: threshold
45 integer, public :: maxiter
46
47contains
48
49
50 ! ---------------------------------------------------------
51 subroutine poisson_cg_init(thr, itr)
52 integer, intent(in) :: itr
53 real(real64), intent(in) :: thr
54
55 push_sub(poisson_cg_init)
56 threshold = thr
57 maxiter = itr
58 pop_sub(poisson_cg_init)
59 end subroutine poisson_cg_init
60
61
62 ! ---------------------------------------------------------
63 subroutine poisson_cg_end
64
65 end subroutine poisson_cg_end
66
67
68 ! ---------------------------------------------------------
69 subroutine poisson_cg1(namespace, der, corrector, pot, rho)
70 type(namespace_t), intent(in) :: namespace
71 type(derivatives_t), target, intent(in) :: der
72 type(poisson_corr_t), intent(in) :: corrector
73 real(real64), intent(inout) :: pot(:)
74 real(real64), intent(in) :: rho(:)
75
76 integer :: iter
77 real(real64) :: res
78 real(real64), allocatable :: wk(:), lwk(:), zk(:), pk(:)
79 type(c_ptr) :: userdata(0) ! workaround, literal [c_ptr::] crashes ifort, eventually encapsulate der_pointer and mesh_pointer
80
81 push_sub(poisson_cg1)
82
83 safe_allocate( wk(1:der%mesh%np_part))
84 safe_allocate(lwk(1:der%mesh%np_part))
85 safe_allocate( zk(1:der%mesh%np_part))
86 safe_allocate( pk(1:der%mesh%np_part))
87
88 ! build initial guess for the potential
89 wk(1:der%mesh%np) = pot(1:der%mesh%np)
90 call poisson_boundary_conditions(corrector, der%mesh, rho, wk)
91 call dderivatives_lapl(der, wk, lwk, ghost_update = .true., set_bc = .false.)
92
93 zk(1:der%mesh%np) = -m_four*m_pi*rho(1:der%mesh%np) - lwk(1:der%mesh%np)
94 safe_deallocate_a(wk)
95 safe_deallocate_a(lwk) ! they are no longer needed
96
97 der_pointer => der
98 mesh_pointer => der%mesh
99 call lalg_copy(der%mesh%np, zk, pk)
100 pk(der%mesh%np + 1:) = m_zero
101 iter = maxiter
102 call dconjugate_gradients(der%mesh%np, pk, zk, internal_laplacian_op, internal_dotp, iter, res, threshold, userdata)
103 if (res >= threshold) then
104 message(1) = 'Conjugate-gradients Poisson solver did not converge.'
105 write(message(2), '(a,i8)') ' Iter = ',iter
106 write(message(3), '(a,e14.6)') ' Res = ', res
107 call messages_warning(3, namespace=namespace)
108 end if
109 nullify(der_pointer, mesh_pointer)
110 pot(1:der%mesh%np) = pot(1:der%mesh%np) + pk(1:der%mesh%np)
111
112 safe_deallocate_a(zk)
113 safe_deallocate_a(pk)
114 pop_sub(poisson_cg1)
115 end subroutine poisson_cg1
117
118 ! ---------------------------------------------------------
119 subroutine poisson_cg2(namespace, der, pot, rho)
120 type(namespace_t), intent(in) :: namespace
121 type(derivatives_t), target, intent(in) :: der
122 real(real64), contiguous, intent(inout) :: pot(:)
123 real(real64), intent(in) :: rho(:)
124
125 integer :: iter, ip
126 real(real64), allocatable :: potc(:), rhs(:)
127 real(real64) :: res
128 type(c_ptr) :: userdata(0) ! workaround, literal [c_ptr::] crashes ifort, eventually encapsulate der_pointer and mesh_pointer
129
130 push_sub(poisson_cg2)
131
132 iter = maxiter
133 der_pointer => der
134 mesh_pointer => der%mesh
135
136 safe_allocate(rhs(1:der%mesh%np))
137 safe_allocate(potc(1:der%mesh%np_part))
138
139 do ip = 1, der%mesh%np
140 rhs(ip) = -4.0_real64*m_pi*rho(ip)
141 end do
142 call lalg_copy(der%mesh%np, pot, potc)
143
144 call dconjugate_gradients(der%mesh%np, potc, rhs, internal_laplacian_op, internal_dotp, iter, res, threshold, userdata)
145
146 if (res >= threshold) then
147 message(1) = 'Conjugate-gradients Poisson solver did not converge.'
148 write(message(2), '(a,i8)') ' Iter = ', iter
149 write(message(3), '(a,e14.6)') ' Res = ', res
150 call messages_warning(3, namespace=namespace)
151 end if
152
153 call lalg_copy(der%mesh%np, potc, pot)
154
155 nullify(der_pointer, mesh_pointer)
156
157 safe_deallocate_a(rhs)
158 safe_deallocate_a(potc)
159
160 pop_sub(poisson_cg2)
161 end subroutine poisson_cg2
162
163end module poisson_cg_oct_m
165!! Local Variables:
166!! mode: f90
167!! coding: utf-8
168!! End:
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_zero
Definition: global.F90:190
real(real64), parameter, public m_four
Definition: global.F90:194
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:188
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:531
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:215
subroutine, public poisson_cg1(namespace, der, corrector, pot, rho)
Definition: poisson_cg.F90:165
subroutine, public poisson_cg_init(thr, itr)
Definition: poisson_cg.F90:147
subroutine, public poisson_cg_end
Definition: poisson_cg.F90:159
subroutine, public internal_laplacian_op(xx, yy, userdata)
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)