Octopus
linear_solver.F90
Go to the documentation of this file.
1!! Copyright (C) 2004 E.S. Kadantsev, M. Marques
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 batch_oct_m
24 use debug_oct_m
26 use global_oct_m
27 use grid_oct_m
29 use iso_c_binding
30 use, intrinsic :: iso_fortran_env
33 use mesh_oct_m
40 use parser_oct_m
43 use smear_oct_m
45 use space_oct_m
48
49 implicit none
50
51 private
52
53 public :: &
63
65 private
66 integer, public :: solver
67 type(preconditioner_t), public :: pre
68 integer :: max_iter
69 type(multigrid_t), allocatable :: mgrid
70 end type linear_solver_t
71
72
74 private
75 type(namespace_t), pointer :: namespace
76 type(linear_solver_t), pointer :: ls
77 type(hamiltonian_elec_t), pointer :: hm
78 type(mesh_t), pointer :: mesh
79 type(states_elec_t), pointer :: st
80 integer :: ist
81 integer :: ik
82 real(real64) :: dshift
83 complex(real64) :: zshift
85
86 type(linear_solver_args_t) :: args
87
88contains
89
90 ! ---------------------------------------------------------
91 subroutine linear_solver_init(this, namespace, gr, states_are_real, mc, space)
92 type(linear_solver_t), intent(out) :: this
93 type(namespace_t), intent(in) :: namespace
94 type(grid_t), intent(inout) :: gr
95 logical, intent(in) :: states_are_real
96 type(multicomm_t), intent(in) :: mc
97 class(space_t), intent(in) :: space
98
99 integer :: fsolver
100 integer :: defsolver
101
102 push_sub(linear_solver_init)
103
104 !%Variable LinearSolver
105 !%Type integer
106 !%Default qmr_symmetric
107 !%Section Linear Response::Solver
108 !%Description
109 !% Method for solving linear equations, which occur for Sternheimer linear
110 !% response and OEP. The solvers vary in speed, reliability (ability to
111 !% converge), and domain of applicability. QMR solvers are most reliable.
112 !%Option bicgstab 4
113 !% Biconjugate gradients stabilized. Slower than <tt>cg</tt>, but more reliable.
114 !% General matrices.
115 !%Option cg 5
116 !% Conjugate gradients. Fast but unreliable. Hermitian matrices only
117 !% (no eta in Sternheimer).
118 !%Option multigrid 7
119 !% Multigrid solver, currently only Gauss-Jacobi (experimental).
120 !% Slow, but fairly reliable. General matrices.
121 !%Option qmr_symmetric 81
122 !% Quasi-minimal residual solver, for (complex) symmetric matrices. [Real symmetric
123 !% is equivalent to Hermitian.] Slightly slower than <tt>bicgstab</tt> but more reliable.
124 !% For Sternheimer, must be real wavefunctions, but can have eta.
125 !%Option qmr_symmetrized 82
126 !% Quasi-minimal residual solver, using the symmetrized form <math>A^\dagger A x = A^\dagger y</math> instead of
127 !% <math>A x = y</math>. Reliable but very slow. General matrices.
128 !%Option qmr_dotp 83
129 !% Quasi-minimal residual solver, for Hermitian matrices, using the
130 !% symmetric algorithm with conjugated dot product (experimental). Slightly slower than <tt>bicgstab</tt>
131 !% but more reliable. Can always be used in Sternheimer.
132 !%Option qmr_general 84
133 !% Quasi-minimal residual solver, for general matrices, using the
134 !% most general form of the algorithm. Slow and unreliable.
135 !%Option sos 9
136 !% Sum over states: the Sternheimer equation is solved by using
137 !% the explicit solution in terms of the ground-state
138 !% wavefunctions. You need unoccupied states to use this method.
139 !% Unlike the other methods, may not give the correct answer.
140 !%Option idrs 11
141 !% This is the "Induced Dimension Reduction", IDR(s) (for s=4). IDR(s) is a robust and efficient short recurrence
142 !% Krylov subspace method for solving large nonsymmetric systems of linear equations. It is described in
143 !% [Peter Sonneveld and Martin B. van Gijzen, SIAM J. Sci. Comput. 31, 1035 (2008)]. We have adapted the code
144 !% released by M. B. van Gizjen [http://ta.twi.tudelft.nl/nw/users/gijzen/IDR.html].
145 !%End
146
147 if (conf%devel_version) then
148 defsolver = option__linearsolver__qmr_dotp
149 else
150 if (states_are_real) then
151 defsolver = option__linearsolver__qmr_symmetric
152 ! in this case, it is equivalent to LS_QMR_DOTP
153 else
154 defsolver = option__linearsolver__qmr_symmetrized
155 end if
156 end if
157 call parse_variable(namespace, "LinearSolver", defsolver, fsolver)
158
159 ! set up pointer for dot product and norm in QMR solvers
160 call mesh_init_mesh_aux(gr)
162 !the last 2 digits select the linear solver
163 this%solver = mod(fsolver, 100)
165 call preconditioner_init(this%pre, namespace, gr, mc, space)
166
167 !%Variable LinearSolverMaxIter
168 !%Type integer
169 !%Default 1000
170 !%Section Linear Response::Solver
171 !%Description
172 !% Maximum number of iterations the linear solver does, even if
173 !% convergence is not achieved.
174 !%End
175 call parse_variable(namespace, "LinearSolverMaxIter", 1000, this%max_iter)
177 call messages_print_with_emphasis(msg='Linear Solver', namespace=namespace)
179 ! solver
180 select case (this%solver)
181 case (option__linearsolver__cg)
182 message(1)='Linear Solver: Conjugate Gradients'
183
184 case (option__linearsolver__bicgstab)
185 message(1)='Linear Solver: Biconjugate Gradients Stabilized'
187 case (option__linearsolver__idrs)
188 message(1)='Linear Solver: IDRS'
189
190 case (option__linearsolver__multigrid)
191 message(1)='Multigrid (currently only Gauss-Jacobi - EXPERIMENTAL)'
192
193 case (option__linearsolver__qmr_symmetric)
194 message(1)='Linear Solver: Quasi-Minimal Residual, for symmetric matrix'
195
196 case (option__linearsolver__qmr_symmetrized)
197 message(1)='Linear Solver: Quasi-Minimal Residual, for symmetrized matrix'
198
199 case (option__linearsolver__qmr_dotp)
200 message(1)='Linear Solver: Quasi-Minimal Residual, symmetric with conjugated dot product'
201
202 case (option__linearsolver__qmr_general)
203 message(1)='Linear Solver: Quasi-Minimal Residual, general algorithm'
204
205 case (option__linearsolver__sos)
206 message(1)='Linear Solver: Sum-over-States'
207 end select
208
209 call messages_info(1, namespace=namespace)
210
211 call messages_print_with_emphasis(namespace=namespace)
212
213 if (this%solver == option__linearsolver__multigrid) then
214 call messages_experimental("Multigrid linear solver")
215
216 safe_allocate(this%mgrid)
217 call multigrid_init(this%mgrid, namespace, space, gr, gr%der, gr%stencil, mc)
218 end if
219
220 if (this%solver == option__linearsolver__qmr_dotp) then
221 call messages_experimental("QMR solver (symmetric with conjugated dot product)")
222 end if
223
224 pop_sub(linear_solver_init)
225 end subroutine linear_solver_init
226
227 ! ---------------------------------------------------------
228 subroutine linear_solver_end(this)
229 type(linear_solver_t), intent(inout) :: this
230 this%solver = -1
231
232 call preconditioner_end(this%pre)
233 if (allocated(this%mgrid)) then
234 call multigrid_end(this%mgrid)
235 safe_deallocate_a(this%mgrid)
236 end if
237
238 end subroutine linear_solver_end
239
240
241 ! ---------------------------------------------------------
242 integer function linear_solver_ops_per_iter(this) result(n)
243 type(linear_solver_t), intent(inout) :: this
244
245 select case (this%solver)
246 case (option__linearsolver__bicgstab)
247 n = 2
248 case default ! LS_CG, LS_MULTIGRID, LS_QMR, LS_SOS
249 n = 1
250 end select
251
252 end function linear_solver_ops_per_iter
253
254 ! ----------------------------------------------------------
255
256 subroutine linear_solver_obsolete_variables(namespace, old_prefix, new_prefix)
257 type(namespace_t), intent(in) :: namespace
258 character(len=*), intent(in) :: old_prefix
259 character(len=*), intent(in) :: new_prefix
260
261 call messages_obsolete_variable(namespace, trim(old_prefix)//"LinearSolver", trim(new_prefix)//"LinearSolver")
262 call messages_obsolete_variable(namespace, trim(old_prefix)//"LinearSolverMaxIter", trim(new_prefix)//"LinearSolverMaxIter")
263
264 call preconditioner_obsolete_variables(namespace, old_prefix, new_prefix)
265
267
268#include "undef.F90"
269
270#include "real.F90"
271
272#include "linear_solver_inc.F90"
273
274#include "undef.F90"
275
276#include "complex.F90"
277#include "linear_solver_inc.F90"
278
279
280
281end module linear_solver_oct_m
282
283!! Local Variables:
284!! mode: f90
285!! coding: utf-8
286!! End:
This module implements batches of mesh functions.
Definition: batch.F90:135
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
type(conf_t), public conf
Global instance of Octopus configuration.
Definition: global.F90:180
This module implements the underlying real-space grid.
Definition: grid.F90:119
subroutine, public dlinear_solver_solve_hxey_batch(this, namespace, hm, mesh, st, xb, yb, shift, tol, residue, iter_used, occ_response, use_initial_guess)
subroutine, public zlinear_solver_solve_hxey(this, namespace, hm, mesh, st, ist, ik, x, y, shift, tol, residue, iter_used, occ_response)
This subroutine calculates the solution of (H + shift) x = y Typically shift = - eigenvalue + omega.
subroutine, public dlinear_solver_solve_hxey(this, namespace, hm, mesh, st, ist, ik, x, y, shift, tol, residue, iter_used, occ_response)
This subroutine calculates the solution of (H + shift) x = y Typically shift = - eigenvalue + omega.
integer function, public linear_solver_ops_per_iter(this)
subroutine, public linear_solver_end(this)
subroutine, public linear_solver_init(this, namespace, gr, states_are_real, mc, space)
subroutine, public zlinear_solver_solve_hxey_batch(this, namespace, hm, mesh, st, xb, yb, shift, tol, residue, iter_used, occ_response, use_initial_guess)
subroutine, public linear_solver_obsolete_variables(namespace, old_prefix, new_prefix)
This module defines functions over batches of mesh functions.
Definition: mesh_batch.F90:118
This module defines various routines, operating on mesh functions.
subroutine, public mesh_init_mesh_aux(mesh)
Initialise a pointer to the grid/mesh, that is globally exposed, such that low level mesh operations ...
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:904
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1029
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1069
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:600
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
subroutine, public preconditioner_end(this)
subroutine, public preconditioner_obsolete_variables(namespace, old_prefix, new_prefix)
subroutine, public preconditioner_init(this, namespace, gr, mc, space)
This module is intended to contain "only mathematical" functions and procedures.
Definition: solvers.F90:117