Octopus
eigensolver.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-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 batch_oct_m
24 use debug_oct_m
32 use global_oct_m
33 use grid_oct_m
37 use, intrinsic :: iso_fortran_env
41 use loct_oct_m
42 use mesh_oct_m
46 use mpi_oct_m
50 use parser_oct_m
54 use smear_oct_m
55 use space_oct_m
62 use types_oct_m
63 use unit_oct_m
66 use xc_oct_m
67
68 implicit none
69
70 private
71 public :: &
75
76 type eigensolver_t
77 private
78 integer, public :: es_type
79
80 real(real64), public :: tolerance
81 integer, public :: es_maxiter
82
83 real(real64) :: tau
84 real(real64) :: tau0
85 real(real64) :: time
86 integer :: it_propagator
87 type(potential_interpolation_t) :: vks_old
88 real(real64), allocatable :: normalization_energies(:, :)
89 ! !! evolution eigensolver
90 real(real64), allocatable :: normalization_energies_prev(:, :)
92 logical :: variable_timestep
93
95 real(real64), allocatable, public :: diff(:, :)
96 integer, public :: matvec
97 integer, allocatable, public :: converged(:)
98
100 type(preconditioner_t), public :: pre
101
103 type(subspace_t) :: sdiag
104
105 integer :: rmmdiis_minimization_iter
106
107 logical, public :: folded_spectrum
108
109 ! cg options
110 logical, public :: orthogonalize_to_all
111 integer, public :: conjugate_direction
112 real(real64), public :: energy_change_threshold
113
114 ! Chebyshev filtering options
115 type(eigen_chebyshev_t), public :: cheby_params
117 type(exponential_t) :: exponential_operator
118 contains
119 procedure :: run => eigensolver_run
120 procedure :: set_lower_bound_is_known => eigensolver_set_lower_bound_is_known
121 end type eigensolver_t
122
123
124 integer, public, parameter :: &
125 RS_PLAN = 11, &
126 rs_cg = 5, &
127 rs_evo = 9, &
128 rs_rmmdiis = 10, &
129 rs_chebyshev = 12
130
131contains
132
133 ! ---------------------------------------------------------
134 subroutine eigensolver_init(eigens, namespace, gr, st, hm, mc, space, deactivate_oracle)
135 type(eigensolver_t), intent(out) :: eigens
136 type(namespace_t), intent(in) :: namespace
137 type(grid_t), intent(in) :: gr
138 type(states_elec_t), intent(in) :: st
139 type(hamiltonian_elec_t), intent(in) :: hm
140 type(multicomm_t), intent(in) :: mc
141 class(space_t), intent(in) :: space
142 logical, optional, intent(in) :: deactivate_oracle
143
144 integer :: default_iter
145 real(real64) :: default_tol
146 real(real64) :: mem
147
148 push_sub(eigensolver_init)
149
150 !%Variable Eigensolver
151 !%Type integer
152 !%Section SCF::Eigensolver
153 !%Description
154 !% Which eigensolver to use to obtain the lowest eigenvalues and
155 !% eigenfunctions of the Kohn-Sham Hamiltonian. The default is
156 !% conjugate gradients (<tt>cg</tt>), except that when parallelization in states is
157 !% enabled, the default is <tt>chebyshev_filter</tt>.
158 !%Option cg 5
159 !% Conjugate-gradients algorithm.
160 !%Option plan 11
161 !% Preconditioned Lanczos scheme. Ref: Y. Saad, A. Stathopoulos, J. Chelikowsky, K. Wu and S. Ogut,
162 !% "Solution of Large Eigenvalue Problems in Electronic Structure Calculations", <i>BIT</i> <b>36</b>, 1 (1996).
163 !%Option evolution 9
164 !% (Experimental) Propagation in imaginary time.
165 !% This eigensolver uses a time propagation in imaginary time (see, e.g., Aichinger, M. & Krotscheck, E.,
166 !% Computational Materials Science 34, 188–212 (2005), 10.1016/j.commatsci.2004.11.002).
167 !% The timestep is set using <tt>EigensolverImaginaryTime</tt>. The convergence typically depends
168 !% on the total imaginary time in a propagation which means that it should be faster with larger
169 !% timesteps. However, simulations typically diverge above a certain timestep that depends on the system.
170 !% In general, it is advisable to use an exponential method that always converges, especially for large
171 !% timesteps, i.e., set <tt>TDExponentialMethod</tt> to <tt>lanczos</tt> or <tt>chebyshev</tt>.
172 !% The propagation method can be set with <tt>ImaginaryTimePropagator</tt> and variable timestepping
173 !% can be enabled with <tt>ImaginaryTimeVariableTimestep</tt>.
174 !% Moreover, this method usually converges quite slowly, so you might need to increase <tt>MaximumIter</tt>.
175 !% It is incompatible with smearing for the occupations.
176 !%Option rmmdiis 10
177 !% Residual minimization scheme, direct inversion in the
178 !% iterative subspace eigensolver, based on the implementation of
179 !% Kresse and Furthm&uuml;ller [<i>Phys. Rev. B</i> <b>54</b>, 11169
180 !% (1996)]. This eigensolver requires almost no orthogonalization
181 !% so it can be considerably faster than the other options for
182 !% large systems. To improve its performance a large number of <tt>ExtraStates</tt>
183 !% are required (around 10-20% of the number of occupied states).
184 !% Note: with <tt>unocc</tt>, you will need to stop the calculation
185 !% by hand, since the highest states will probably never converge.
186 !% Usage with more than one block of states per node is experimental, unfortunately.
187 !%Option chebyshev_filter 12
188 !% Chebyshev polynomials are used to construct a spectral filter that is iteratively applied to a trial subspace,
189 !% amplifying a subset of the lowest eigenvalues of the Hamiltonian, which effectively isolates the invariant
190 !% subspace associated with the these states. The filtered subspace is projected to define a reduced eigenvalue problem,
191 !% which is then solved using dense diagonalisation. Finally, the eigenstates of the original Hamiltonian are recovered
192 !% via subspace rotation. For further details, see [Zhou et. al.](http://dx.doi.org/10.1016/j.jcp.2014.06.056)
193 !%End
194 call parse_variable(namespace, 'Eigensolver', rs_chebyshev, eigens%es_type)
196 if(st%parallel_in_states .and. .not. eigensolver_parallel_in_states(eigens)) then
197 message(1) = "The selected eigensolver is not parallel in states."
198 message(2) = "Please use the rmmdiis or Chebyshev filtering eigensolvers."
199 call messages_fatal(2, namespace=namespace)
200 end if
201
202 call messages_obsolete_variable(namespace, 'EigensolverVerbose')
203 call messages_obsolete_variable(namespace, 'EigensolverSubspaceDiag', 'SubspaceDiagonalization')
204
205 default_iter = 25
207 select case(eigens%es_type)
208 case(rs_cg)
209 !%Variable CGOrthogonalizeAll
210 !%Type logical
211 !%Default no
212 !%Section SCF::Eigensolver
213 !%Description
214 !% Used by the cg solver only.
215 !% During the cg iterations, the current band can be orthogonalized
216 !% against all other bands or only against the lower bands. Orthogonalizing
217 !% against all other bands can improve convergence properties, whereas
218 !% orthogonalizing against lower bands needs less operations.
219 !% Moreover, orthogonalizing against all bands can make converging
220 !% the highest band or unoccupied bands more difficult.
221 !%End
222 call parse_variable(namespace, 'CGOrthogonalizeAll', .false., eigens%orthogonalize_to_all)
223
224 !%Variable CGDirection
225 !%Type integer
226 !%Section SCF::Eigensolver
227 !%Description
228 !% Used by the cg solver only.
229 !% The conjugate direction is updated using a certain coefficient to the previous
230 !% direction. This coeffiction can be computed in different ways. The default is
231 !% to use Fletcher-Reeves (FR), an alternative is Polak-Ribiere (PR).
232 !%Option fletcher 1
233 !% The coefficient for Fletcher-Reeves consists of the current norm of the
234 !% steepest descent vector divided by that of the previous iteration.
235 !%Option polak 2
236 !% For the Polak-Ribiere scheme, a product of the current with the previous
237 !% steepest descent vector is subtracted in the nominator.
238 !%End
239 call parse_variable(namespace, 'CGDirection', option__cgdirection__fletcher, eigens%conjugate_direction)
240
241 !%Variable CGEnergyChangeThreshold
242 !%Type float
243 !%Section SCF::Eigensolver
244 !%Default 0.1
245 !%Description
246 !% Used by the cg solver only.
247 !% For each band, the CG iterations are stopped when the change in energy is smaller than the
248 !% change in the first iteration multiplied by this factor. This limits the number of CG
249 !% iterations for each band, while still showing good convergence for the SCF cycle. The criterion
250 !% is discussed in Sec. V.B.6 of Payne et al. (1992), Rev. Mod. Phys. 64, 4.
251 !% The default value is 0.1, which is usually a good choice for LDA and GGA potentials. If you
252 !% are solving the OEP equation, you might want to set this value to 1e-3 or smaller. In general,
253 !% smaller values might help if you experience convergence problems.
254 !% For very small convergence tolerances, choose 0 to disable this criterion.
255 !%End
256 call parse_variable(namespace, 'CGEnergyChangeThreshold', 0.1_real64, eigens%energy_change_threshold)
257
258 case(rs_plan)
259 case(rs_evo)
260 call messages_experimental("imaginary-time evolution eigensolver")
261
262 !%Variable EigensolverImaginaryTime
263 !%Type float
264 !%Default 0.1
265 !%Section SCF::Eigensolver
266 !%Description
267 !% The imaginary-time step that is used in the imaginary-time evolution
268 !% method (<tt>Eigensolver = evolution</tt>) to obtain the lowest eigenvalues/eigenvectors.
269 !% It must satisfy <tt>EigensolverImaginaryTime > 0</tt>.
270 !% Increasing this value can make the propagation faster, but could lead to unstable propagations.
271 !%End
272 call parse_variable(namespace, 'EigensolverImaginaryTime', 0.1_real64, eigens%tau)
273 if(eigens%tau <= m_zero) call messages_input_error(namespace, 'EigensolverImaginaryTime')
274 ! save initial timestep
275 eigens%tau0 = eigens%tau
276
277 call exponential_init(eigens%exponential_operator, namespace)
278
279 if(st%smear%method /= smear_semiconductor .and. st%smear%method /= smear_fixed_occ) then
280 message(1) = "Smearing of occupations is incompatible with imaginary time evolution."
281 call messages_fatal(1, namespace=namespace)
282 end if
283
284 !%Variable ImaginaryTimePropagator
285 !%Type integer
286 !%Section SCF::Eigensolver
287 !%Default it_forward_euler
288 !%Description
289 !% The propagation method for imaginary-time evolution.
290 !%Option it_forward_euler 1
291 !% Approximate the evolution operator by one forward Euler step with the exponential:
292 !% <math>
293 !% U_{\rm FE}(t+\delta t, t) = \exp \left( -\tau H_{t}\right)\,.
294 !% </math>
295 !% This scheme is first order.
296 !%Option it_expmid 2
297 !% Similar to forward Euler, but evaluate the Hamiltonian at the half-timestep by
298 !% extrapolation:
299 !% <math>
300 !% U_{\rm EM}(t+\delta t, t) = \exp \left( -\tau H_{t+\delta t/2}\right)\,.
301 !% </math>
302 !% This scheme is second order.
303 !%End
304 call parse_variable(namespace, 'ImaginaryTimePropagator', it_forward_euler, eigens%it_propagator)
305 ! initialize potential interpolation
306 if (eigens%it_propagator == it_expmid) then
307 call hm%ks_pot%init_interpolation(eigens%vks_old)
308 call hm%ks_pot%run_zero_iter(eigens%vks_old)
309 end if
310
311 !%Variable ImaginaryTimeVariableTimestep
312 !%Type logical
313 !%Default no
314 !%Section SCF::Eigensolver
315 !%Description
316 !% Enable variable timesteps for the imaginary time propagation.
317 !%End
318 call parse_variable(namespace, 'ImaginaryTimeVariableTimestep', .false., eigens%variable_timestep)
319
320 eigens%time = m_zero
321
322 safe_allocate(eigens%normalization_energies(1:st%nst, 1:st%nik))
323 safe_allocate(eigens%normalization_energies_prev(1:st%nst, 1:st%nik))
324
325 case(rs_rmmdiis)
326 default_iter = 5
327
328 !%Variable EigensolverMinimizationIter
329 !%Type integer
330 !%Default 0
331 !%Section SCF::Eigensolver
332 !%Description
333 !% During the first iterations, the RMMDIIS eigensolver requires
334 !% some steepest-descent minimizations to improve
335 !% convergence. This variable determines the number of those
336 !% minimizations.
337 !%End
338
339 call parse_variable(namespace, 'EigensolverMinimizationIter', 0, eigens%rmmdiis_minimization_iter)
340
341 if(gr%use_curvilinear) call messages_experimental("RMMDIIS eigensolver for curvilinear coordinates")
342
343 case(rs_chebyshev)
344 !%Variable ChebyshevFilterLanczosOrder
345 !%Type integer
346 !%Default -1
347 !%Section SCF::Eigensolver
348 !%Description
349 !% Used by the Chebyshev filter only.
350 !% The number of Lanczos iterations used to construct the tridiagonal matrix,
351 !% from which the upper bound of H is estimated.
352 !% A value in the range 4 <= ChebyshevFilterLanczosOrder <= 10 is reasonable.
353 !% Values greater than 30 will raise an assertion.
354 !%
355 !% The default value, -1, indicate that the order is selected automatically.
356 !% In this case, the trial vector is also reused to make the procedure faster.
357 !%End
358 call parse_variable(namespace, 'ChebyshevFilterLanczosOrder', default_chebyshev_params%n_lanczos, &
359 eigens%cheby_params%n_lanczos)
360
361 ! TODO Rewrite this, having changed the behaviour
362 !%Variable ChebyshevFilterDegree
363 !%Type integer
364 !%Default 25
365 !%Section SCF::Eigensolver
366 !%Description
367 !% Used by the Chebyshev filter only.
368 !% The degree of the Chebyshev polynomial used to dampen the interval of eigenstates one is not interested in.
369 !% If used in conjunction with "OptimizeChebyshevFilterDegree", which is the default, "ChebyshevFilterDegree" defines the
370 !% the maximum Chebyshev polynomial degree Octopus will consider when determining an approximate, optimal degree.
371 !%
372 !% If not used in conjunction with "OptimizeChebyshevFilterDegree", this defines the polynomial degree used for all SCF steps.
373 !% The larger the degree, the larger the separation between the subspaces, which will reduce the number of SCF iterations
374 !% required to reach convergence. However, ChebyshevFilterDegree also directly correlates with the number of matrix-vector
375 !% products performed on the Hamiltonian per SCF step, and so larger values result in slower SCF cycles.
376 !% A value in the range 8 <= ChebyshevFilterDegree <= 20 is reasonable.
377 !%End
378 call parse_variable(namespace, 'ChebyshevFilterDegree', default_chebyshev_params%degree, eigens%cheby_params%degree)
379
380 !%Variable OptimizeChebyshevFilterDegree
381 !%Type logical
382 !%Default yes
383 !%Section SCF::Eigensolver
384 !%Description
385 !% Used by the Chebyshev filter only.
386 !% Octopus generates a best-estimate for the degree of the Chebyshev polynomial used to filter the subspace.
387 !% A separate estimate is generated for each state block, per SCF iteration. Note that if running parallelism
388 !% over states, the block/batch containing the largest eigenstates will converge more slowly and will
389 !% therefore use a larger degree relative to all other batches. One should therefore avoid setting "ChebyshevFilterDegree"
390 !% to an excessive value (for example > 50). For more details regarding how the degree is estimated, one can
391 !% refer to Section 5.4 in "Computer Physics Communications 187 (2015) 98–105"
392 !% (http://dx.doi.org/10.1016/j.cpc.2014.10.015).
393 !%
394 !% This is deactivated by default for spinors as this is not found to be advantageous in test systems.
395 !%End
396 if (st%d%ispin == spinors .or. optional_default(deactivate_oracle, .false.)) then
397 default_chebyshev_params%optimize_degree = .false.
398 end if
399 call parse_variable(namespace, 'OptimizeChebyshevFilterDegree', default_chebyshev_params%optimize_degree, &
400 eigens%cheby_params%optimize_degree)
401
402 !%Variable ChebyshevFilterBoundMixing
403 !%Type float
404 !%Default 0.5
405 !%Section SCF::Eigensolver
406 !%Description
407 !% In the first application of the filter, for the first SCF step, the initial lower bound estimate
408 !% is defined as a linear combination of the smallest and largest eigenvalues of the Hamiltonian.
409 !% The bound mixing determines the proportion of linear mixing, beta:
410 !% $b_{lower} = beta min{\lambda} + (\beta - 1) max{\lambda}$
411 !% of the smallest and largest eigenvalues.
412 !%End
413 call parse_variable(namespace, 'ChebyshevFilterBoundMixing', default_chebyshev_params%bound_mixing, &
414 eigens%cheby_params%bound_mixing)
415
416 !%Variable ChebyshevFilterNIter
417 !%Type integer
418 !%Default 5
419 !%Section SCF::Eigensolver
420 !%Description
421 !% The max number of iterations in the first SCF step of the Chebyshev solver. In practice this
422 !% does not need to exceed 10, as the eigenstates will vary alot between the first and second
423 !% SCF steps.
424 !%End
425 call parse_variable(namespace, 'ChebyshevFilterNIter', default_chebyshev_params%n_iter, &
426 eigens%cheby_params%n_iter)
427
428 case default
429 call messages_input_error(namespace, 'Eigensolver')
430 end select
431
432 call messages_print_with_emphasis(msg='Eigensolver', namespace=namespace)
433
434 call messages_print_var_option("Eigensolver", eigens%es_type, namespace=namespace)
435
436 call messages_obsolete_variable(namespace, 'EigensolverInitTolerance', 'EigensolverTolerance')
437 call messages_obsolete_variable(namespace, 'EigensolverFinalTolerance', 'EigensolverTolerance')
438 call messages_obsolete_variable(namespace, 'EigensolverFinalToleranceIteration')
439
440 ! this is an internal option that makes the solver use the
441 ! folded operator (H-shift)^2 to converge first eigenvalues around
442 ! the values of shift
443 ! c.f. L. W. Wang and A. Zunger
444 ! JCP 100, 2394 (1994); doi: http://dx.doi.org/10.1063/1.466486
445 eigens%folded_spectrum = .false.
446
447 !%Variable EigensolverTolerance
448 !%Type float
449 !%Section SCF::Eigensolver
450 !%Description
451 !% This is the tolerance for the eigenvectors. The default is 1e-7.
452 !% However, if <tt>ConvRelDens</tt> is defined, the default is set to a tenth of its value.
453 !%End
454 default_tol = 1e-7_real64
455 if (parse_is_defined(namespace, 'ConvRelDens')) then
456 call parse_variable(namespace, 'ConvRelDens', 1e-6_real64, default_tol)
457 default_tol = default_tol / 10.0_real64
458 end if
459 call parse_variable(namespace, 'EigensolverTolerance', default_tol, eigens%tolerance)
460
461 !%Variable EigensolverMaxIter
462 !%Type integer
463 !%Section SCF::Eigensolver
464 !%Description
465 !% Determines the maximum number of iterations that the
466 !% eigensolver will perform if the desired tolerance is not
467 !% achieved. The default is 25 iterations for all eigensolvers
468 !% except for <tt>rmdiis</tt>, which performs only 5 iterations.
469 !% Increasing this value for <tt>rmdiis</tt> increases the convergence speed,
470 !% at the cost of an increased memory footprint.
471 !%End
472 call parse_variable(namespace, 'EigensolverMaxIter', default_iter, eigens%es_maxiter)
473 if(eigens%es_maxiter < 1) call messages_input_error(namespace, 'EigensolverMaxIter')
474
475 if(eigens%es_maxiter > default_iter) then
476 call messages_write('You have specified a large number of eigensolver iterations (')
477 call messages_write(eigens%es_maxiter)
478 call messages_write(').', new_line = .true.)
479 call messages_write('This is not a good idea as it might slow down convergence, even for', new_line = .true.)
480 call messages_write('independent particles, as subspace diagonalization will not be used', new_line = .true.)
481 call messages_write('often enough.')
482 call messages_warning(namespace=namespace)
483 end if
484
485 if (any(eigens%es_type == (/rs_plan, rs_cg, rs_rmmdiis/))) then
486 call preconditioner_init(eigens%pre, namespace, gr, mc, space)
487 end if
488
489 safe_allocate(eigens%diff(1:st%nst, 1:st%nik))
490 eigens%diff(1:st%nst, 1:st%nik) = 0
491
492 safe_allocate(eigens%converged(1:st%nik))
493 eigens%converged(1:st%nik) = 0
494 eigens%matvec = 0
495
496 call eigens%sdiag%init(namespace, st)
497
498 ! print memory requirements
499 select case(eigens%es_type)
500 case(rs_rmmdiis)
501 call messages_write('Info: The rmmdiis eigensolver requires ')
502 mem = (m_two*eigens%es_maxiter - m_one)*st%block_size*real(gr%np_part, real64)
503 if(states_are_real(st)) then
504 mem = mem*8.0_real64
505 else
506 mem = mem*16.0_real64
507 end if
508 call messages_write(mem, units = unit_megabytes, fmt = '(f9.1)')
509 call messages_write(' of additional')
510 call messages_new_line()
511 call messages_write(' memory. This amount can be reduced by decreasing the value')
512 call messages_new_line()
513 call messages_write(' of the variable StatesBlockSize (currently set to ')
514 call messages_write(st%block_size)
515 call messages_write(').')
516 call messages_info()
517 end select
518
519 call messages_print_with_emphasis(namespace=namespace)
520
521 pop_sub(eigensolver_init)
522 end subroutine eigensolver_init
523
524
525 ! ---------------------------------------------------------
526 subroutine eigensolver_end(eigens)
527 type(eigensolver_t), intent(inout) :: eigens
528
529 push_sub(eigensolver_end)
530
531 select case(eigens%es_type)
532 case(rs_plan, rs_cg, rs_rmmdiis)
533 call preconditioner_end(eigens%pre)
534 end select
535
536 safe_deallocate_a(eigens%converged)
537 safe_deallocate_a(eigens%diff)
538
539 safe_deallocate_a(eigens%normalization_energies)
540 safe_deallocate_a(eigens%normalization_energies_prev)
541
542 pop_sub(eigensolver_end)
543 end subroutine eigensolver_end
544
545
546 ! ---------------------------------------------------------
547 subroutine eigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter, conv, nstconv)
548 class(eigensolver_t), intent(inout) :: eigens
549 type(namespace_t), intent(in) :: namespace
550 type(grid_t), intent(in) :: gr
551 type(states_elec_t), intent(inout) :: st
552 type(hamiltonian_elec_t), intent(inout) :: hm
553 class(space_t), intent(in) :: space
554 type(partner_list_t), intent(in) :: ext_partners
555 integer, intent(in) :: iter
556 logical, optional, intent(out) :: conv
557 integer, optional, intent(in) :: nstconv
558 ! !< the convergence criteria
559
560 integer :: nstconv_
561#ifdef HAVE_MPI
562 logical :: conv_reduced
563 integer :: ist, outcount, lmatvec
564 real(real64), allocatable :: ldiff(:), leigenval(:)
565 real(real64), allocatable :: ldiff_out(:), leigenval_out(:)
566 integer, allocatable :: lconv(:)
567#endif
568
569 call profiling_in("EIGEN_SOLVER")
570 push_sub(eigensolver_run)
571
572 if(present(conv)) conv = .false.
573 if(present(nstconv)) then
574 nstconv_ = nstconv
575 else
576 nstconv_ = st%nst
577 end if
578
579 eigens%matvec = 0
580
581 if(mpi_world%is_root() .and. eigensolver_has_progress_bar(eigens) .and. .not. debug%info) then
582 call loct_progress_bar(-1, st%lnst*st%d%kpt%nlocal)
583 end if
584
585 if (states_are_real(st)) then
586 call deigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
587 else
588 call zeigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter)
589 end if
590
591 if(mpi_world%is_root() .and. eigensolver_has_progress_bar(eigens) .and. .not. debug%info) then
592 write(stdout, '(1x)')
593 end if
594
595 if(present(conv)) conv = all(eigens%converged(st%d%kpt%start:st%d%kpt%end) >= nstconv_)
596
597#ifdef HAVE_MPI
598 if (st%d%kpt%parallel) then
599 if (present(conv)) then
600 call st%d%kpt%mpi_grp%allreduce(conv, conv_reduced, 1, mpi_logical, mpi_land)
601 conv = conv_reduced
602 end if
603
604 lmatvec = eigens%matvec
605 call st%d%kpt%mpi_grp%allreduce(lmatvec, eigens%matvec, 1, mpi_integer, mpi_sum)
606
607 safe_allocate(lconv(1:st%d%kpt%nlocal))
608 lconv(1:st%d%kpt%nlocal) = eigens%converged(st%d%kpt%start:st%d%kpt%end)
609 call lmpi_gen_allgatherv(st%d%kpt%nlocal, lconv, outcount, eigens%converged, st%d%kpt%mpi_grp)
610 assert(outcount == st%nik)
611 safe_deallocate_a(lconv)
612
613 ! every node needs to know all eigenvalues (and diff)
614 safe_allocate(ldiff(1:st%d%kpt%nlocal))
615 safe_allocate(leigenval(1:st%d%kpt%nlocal))
616 safe_allocate(ldiff_out(1:st%nik))
617 safe_allocate(leigenval_out(1:st%nik))
618 do ist = st%st_start, st%st_end
619 ldiff(1:st%d%kpt%nlocal) = eigens%diff(ist, st%d%kpt%start:st%d%kpt%end)
620 leigenval(1:st%d%kpt%nlocal) = st%eigenval(ist, st%d%kpt%start:st%d%kpt%end)
621 call lmpi_gen_allgatherv(st%d%kpt%nlocal, ldiff, outcount, ldiff_out, st%d%kpt%mpi_grp)
622 eigens%diff(ist, :) = ldiff_out
623 assert(outcount == st%nik)
624 call lmpi_gen_allgatherv(st%d%kpt%nlocal, leigenval, outcount, leigenval_out, st%d%kpt%mpi_grp)
625 st%eigenval(ist, :) = leigenval_out
626 assert(outcount == st%nik)
627 end do
628 safe_deallocate_a(ldiff)
629 safe_deallocate_a(ldiff_out)
630 safe_deallocate_a(leigenval)
631 safe_deallocate_a(leigenval_out)
632 end if
633#endif
634
635 pop_sub(eigensolver_run)
636 call profiling_out("EIGEN_SOLVER")
637 end subroutine eigensolver_run
638
639
640 ! ---------------------------------------------------------
641 logical function eigensolver_parallel_in_states(this) result(par_stat)
642 type(eigensolver_t), intent(in) :: this
643
645
646 par_stat = .false.
647
648 select case(this%es_type)
650 par_stat = .true.
651 end select
652
655
656
657 ! ---------------------------------------------------------
658 logical function eigensolver_has_progress_bar(this) result(has)
659 type(eigensolver_t), intent(in) :: this
660
662
663 has = .false.
664
665 select case(this%es_type)
666 case(rs_rmmdiis, rs_cg)
667 has = .true.
668 end select
669
672
674 pure subroutine eigensolver_set_lower_bound_is_known(this, known_lower_bound)
675 class(eigensolver_t), intent(inout) :: this
676 logical, intent(in) :: known_lower_bound
677
678 this%cheby_params%known_lower_bound = known_lower_bound
680
681
682#include "undef.F90"
683#include "real.F90"
684#include "eigensolver_inc.F90"
685#include "eigen_plan_inc.F90"
686
687#include "undef.F90"
688#include "complex.F90"
689#include "eigensolver_inc.F90"
690#include "eigen_plan_inc.F90"
692end module eigensolver_oct_m
693
694
695!! Local Variables:
696!! mode: f90
697!! coding: utf-8
698!! 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
type(debug_t), save, public debug
Definition: debug.F90:158
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
type(eigen_chebyshev_t), public default_chebyshev_params
Default Chebyshev input parameters Arguments 1 and 2 taken from 10.1016/j.jcp.2006....
integer, parameter, public it_expmid
integer, parameter, public it_forward_euler
subroutine zeigensolver_run(eigens, namespace, mesh, st, hm, space, ext_partners, iter)
integer, parameter, public rs_evo
subroutine, public eigensolver_init(eigens, namespace, gr, st, hm, mc, space, deactivate_oracle)
integer, parameter, public rs_cg
subroutine deigensolver_run(eigens, namespace, mesh, st, hm, space, ext_partners, iter)
subroutine eigensolver_run(eigens, namespace, gr, st, hm, space, ext_partners, iter, conv, nstconv)
logical function eigensolver_parallel_in_states(this)
integer, parameter, public rs_chebyshev
logical function eigensolver_has_progress_bar(this)
subroutine, public eigensolver_end(eigens)
integer, parameter, public rs_rmmdiis
pure subroutine eigensolver_set_lower_bound_is_known(this, known_lower_bound)
Set the flag lower_bound_is_known.
integer, parameter, public spinors
subroutine, public exponential_init(te, namespace, full_batch)
real(real64), parameter, public m_two
Definition: global.F90:193
real(real64), parameter, public m_zero
Definition: global.F90:191
real(real64), parameter, public m_one
Definition: global.F90:192
This module implements the underlying real-space grid.
Definition: grid.F90:119
This module defines classes and functions for interaction partners.
A module to handle KS potential, without the external potential.
System information (time, memory, sysname)
Definition: loct.F90:117
subroutine, public loct_progress_bar(a, maxcount)
A wrapper around the progress bar, such that it can be silenced without needing to dress the call wit...
Definition: loct.F90:276
This module defines functions over batches of mesh functions.
Definition: mesh_batch.F90:118
This module defines various routines, operating on mesh functions.
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:898
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1023
subroutine, public messages_new_line()
Definition: messages.F90:1112
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1063
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
This module contains some common usage patterns of MPI routines.
Definition: mpi_lib.F90:117
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:272
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:455
subroutine, public preconditioner_end(this)
subroutine, public preconditioner_init(this, namespace, gr, mc, space)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
integer, parameter, public smear_semiconductor
Definition: smear.F90:173
integer, parameter, public smear_fixed_occ
Definition: smear.F90:173
pure logical function, public states_are_real(st)
This module handles spin dimensions of the states and the k-point distribution.
This module provides routines for communicating states when using states parallelization.
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
This module defines the unit system, used for input and output.
type(unit_t), public unit_megabytes
For large amounts of data (natural code units are bytes)
Definition: xc.F90:116
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
The states_elec_t class contains all electronic wave functions.
int true(void)