Octopus
poisson.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2011 M. Marques, A. Castro, A. Rubio,
2!! G. Bertsch, M. Oliveira
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
22module poisson_oct_m
23 use accel_oct_m
24 use batch_oct_m
27 use comm_oct_m
28 use cube_oct_m
30 use debug_oct_m
32 use fft_oct_m
34 use global_oct_m
35 use index_oct_m
36 use, intrinsic :: iso_fortran_env
39 use math_oct_m
40 use mesh_oct_m
44 use mpi_oct_m
47#ifdef HAVE_OPENMP
48 use omp_lib
49#endif
51 use parser_oct_m
62 use space_oct_m
65 use types_oct_m
68 use xc_cam_oct_m
69
70 implicit none
71
72 private
73 public :: &
74 poisson_t, &
96
97 integer, public, parameter :: &
98 POISSON_DIRECT_SUM = -1, &
99 poisson_fft = 0, &
100 poisson_cg = 5, &
102 poisson_multigrid = 7, &
103 poisson_isf = 8, &
104 poisson_psolver = 10, &
105 poisson_no = -99, &
106 poisson_null = -999
107
108 type poisson_t
109 private
110 type(derivatives_t), pointer, public :: der
111 integer, public :: method = poisson_null
112 integer, public :: kernel
113 type(cube_t), public :: cube
114 type(mesh_cube_parallel_map_t), public :: mesh_cube_map
115 type(poisson_mg_solver_t) :: mg
116 type(poisson_fft_t), public :: fft_solver
117 real(real64), public :: poisson_soft_coulomb_param
118 logical :: all_nodes_default
119 type(poisson_corr_t) :: corrector
120 type(poisson_isf_t) :: isf_solver
121 type(poisson_psolver_t) :: psolver_solver
122 type(poisson_no_t) :: no_solver
123 integer :: nslaves
124 logical, public :: is_dressed = .false.
125 type(photon_mode_t), public :: photons
126#ifdef HAVE_MPI
127 type(MPI_Comm) :: intercomm
128 type(mpi_grp_t) :: local_grp
129 logical :: root
130#endif
131 end type poisson_t
132
133 integer, parameter :: &
134 CMD_FINISH = 1, &
136
137contains
138
139 !-----------------------------------------------------------------
140 subroutine poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx)
141 type(poisson_t), intent(inout) :: this
142 class(space_t), intent(in) :: space
143 type(namespace_t), intent(in) :: namespace
144 type(derivatives_t), target, intent(in) :: der
145 type(multicomm_t), intent(in) :: mc
146 type(stencil_t), intent(in) :: stencil
147 real(real64), optional, intent(in) :: qtot
148 character(len=*), optional, intent(in) :: label
149 integer, optional, intent(in) :: solver
150 logical, optional, intent(in) :: verbose
151 logical, optional, intent(in) :: force_serial
152 logical, optional, intent(in) :: force_cmplx
153
154 logical :: need_cube, isf_data_is_parallel
155 integer :: default_solver, default_kernel, box(space%dim), fft_type, fft_library
156 real(real64) :: fft_alpha
157 character(len=60) :: str
158
159 ! Make sure we do not try to initialize an already initialized solver
160 assert(this%method == poisson_null)
161
162 push_sub(poisson_init)
163
164 if (optional_default(verbose,.true.)) then
165 str = "Hartree"
166 if (present(label)) str = trim(label)
167 call messages_print_with_emphasis(msg=trim(str), namespace=namespace)
168 end if
169
170 this%nslaves = 0
171 this%der => der
172
173 !%Variable DressedOrbitals
174 !%Type logical
175 !%Default false
176 !%Section Hamiltonian::Poisson
177 !%Description
178 !% Allows for the calculation of coupled elecron-photon problems
179 !% by applying the dressed orbital approach. Details can be found in
180 !% https://arxiv.org/abs/1812.05562
181 !% At the moment, N electrons in d (<=3) spatial dimensions, coupled
182 !% to one photon mode can be described. The photon mode is included by
183 !% raising the orbital dimension to d+1 and changing the particle interaction
184 !% kernel and the local potential, where the former is included automatically,
185 !% but the latter needs to by added by hand as a user_defined_potential!
186 !% Coordinate 1-d: electron; coordinate d+1: photon.
187 !%End
188 call parse_variable(namespace, 'DressedOrbitals', .false., this%is_dressed)
189 call messages_print_var_value('DressedOrbitals', this%is_dressed, namespace=namespace)
190 if (this%is_dressed) then
191 assert(present(qtot))
192 call messages_experimental('Dressed Orbitals', namespace=namespace)
193 assert(qtot > m_zero)
194 call photon_mode_init(this%photons, namespace, der%dim-1)
195 call photon_mode_set_n_electrons(this%photons, qtot)
196 if(.not.allocated(this%photons%pol_dipole)) then
197 call photon_mode_compute_dipoles(this%photons, der%mesh)
198 end if
199 if (this%photons%nmodes > 1) then
200 call messages_not_implemented('DressedOrbitals for more than one photon mode', namespace=namespace)
201 end if
202 end if
204 this%all_nodes_default = .false.
205#ifdef HAVE_MPI
206 if (.not. optional_default(force_serial, .false.)) then
207 !%Variable ParallelizationPoissonAllNodes
208 !%Type logical
209 !%Default true
210 !%Section Execution::Parallelization
211 !%Description
212 !% When running in parallel, this variable selects whether the
213 !% Poisson solver should divide the work among all nodes or only
214 !% among the parallelization-in-domains groups.
215 !%End
217 call parse_variable(namespace, 'ParallelizationPoissonAllNodes', .true., this%all_nodes_default)
218 end if
219#endif
221 !%Variable PoissonSolver
222 !%Type integer
223 !%Section Hamiltonian::Poisson
224 !%Description
225 !% Defines which method to use to solve the Poisson equation. Some incompatibilities apply depending on
226 !% dimensionality, periodicity, etc.
227 !% For a comparison of the accuracy and performance of the methods in Octopus, see P Garcia-Risue&ntilde;o,
228 !% J Alberdi-Rodriguez <i>et al.</i>, <i>J. Comp. Chem.</i> <b>35</b>, 427-444 (2014)
229 !% or <a href=http://arxiv.org/abs/1211.2092>arXiV</a>.
230 !% Defaults:
231 !% <br> 1D and 2D: <tt>fft</tt>.
232 !% <br> 3D: <tt>cg_corrected</tt> if curvilinear, <tt>isf</tt> if not periodic, <tt>fft</tt> if periodic.
233 !% <br> Dressed orbitals: <tt>direct_sum</tt>.
234 !%Option NoPoisson -99
235 !% Do not use a Poisson solver at all.
236 !%Option direct_sum -1
237 !% Direct evaluation of the Hartree potential (only for finite systems).
238 !%Option fft 0
239 !% The Poisson equation is solved using FFTs. A cutoff technique
240 !% for the Poisson kernel is selected so the proper boundary
241 !% conditions are imposed according to the periodicity of the
242 !% system. This can be overridden by the <tt>PoissonFFTKernel</tt>
243 !% variable. To choose the FFT library use <tt>FFTLibrary</tt>
244 !%Option cg 5
245 !% Conjugate gradients (only for finite systems).
246 !%Option cg_corrected 6
247 !% Conjugate gradients, corrected for boundary conditions (only for finite systems).
248 !%Option multigrid 7
249 !% Multigrid method (only for finite systems).
250 !%Option isf 8
251 !% Interpolating Scaling Functions Poisson solver (only for finite systems).
252 !%Option psolver 10
253 !% Solver based on Interpolating Scaling Functions as implemented in the PSolver library.
254 !% Parallelization in k-points requires <tt>PoissonSolverPSolverParallelData</tt> = no.
255 !% Requires the PSolver external library.
256 !%End
257
258 default_solver = poisson_fft
259
260 if (space%dim == 3 .and. .not. space%is_periodic()) default_solver = poisson_isf
261
262#ifdef HAVE_CLFFT
263 ! this is disabled, since the difference between solvers are big
264 ! enough to cause problems with the tests.
265 ! if (accel_is_enabled()) default_solver = POISSON_FFT
266#endif
267#ifdef HAVE_CUDA
268 if(accel_is_enabled()) default_solver = poisson_fft
269#endif
270
271 if (space%dim > 3) default_solver = poisson_no ! Kernel for higher dimensions is not implemented.
272
273 if (der%mesh%use_curvilinear) then
274 select case (space%dim)
275 case (1)
276 default_solver = poisson_direct_sum
277 case (2)
278 default_solver = poisson_direct_sum
279 case (3)
280 default_solver = poisson_multigrid
281 end select
282 end if
283
284 if (this%is_dressed) default_solver = poisson_direct_sum
285
286 if (.not. present(solver)) then
287 call parse_variable(namespace, 'PoissonSolver', default_solver, this%method)
288 else
289 this%method = solver
290 end if
291 if (.not. varinfo_valid_option('PoissonSolver', this%method)) call messages_input_error(namespace, 'PoissonSolver')
292 if (optional_default(verbose, .true.)) then
293 select case (this%method)
294 case (poisson_direct_sum)
295 str = "direct sum"
296 case (poisson_fft)
297 str = "fast Fourier transform"
298 case (poisson_cg)
299 str = "conjugate gradients"
301 str = "conjugate gradients, corrected"
302 case (poisson_multigrid)
303 str = "multigrid"
304 case (poisson_isf)
305 str = "interpolating scaling functions"
306 case (poisson_psolver)
307 str = "interpolating scaling functions (from BigDFT)"
308 case (poisson_no)
309 str = "no Poisson solver - Hartree set to 0"
310 end select
311 write(message(1),'(a,a,a)') "The chosen Poisson solver is '", trim(str), "'"
312 call messages_info(1, namespace=namespace)
313 end if
314
315 if (space%dim > 3 .and. this%method /= poisson_no) then
316 call messages_input_error(namespace, 'PoissonSolver', 'Currently no Poisson solver is available for Dimensions > 3')
317 end if
318
319 if (this%method /= poisson_fft) then
320 this%kernel = poisson_fft_kernel_none
321 else
322
323 ! Documentation in cube.F90
324 call parse_variable(namespace, 'FFTLibrary', fftlib_fftw, fft_library)
325
326 !%Variable PoissonFFTKernel
327 !%Type integer
328 !%Section Hamiltonian::Poisson
329 !%Description
330 !% Defines which kernel is used to impose the correct boundary
331 !% conditions when using FFTs to solve the Poisson equation. The
332 !% default is selected depending on the dimensionality and
333 !% periodicity of the system:
334 !% <br>In 1D, <tt>spherical</tt> if finite, <tt>fft_nocut</tt> if periodic.
335 !% <br>In 2D, <tt>spherical</tt> if finite, <tt>cylindrical</tt> if 1D-periodic, <tt>fft_nocut</tt> if 2D-periodic.
336 !% <br>In 3D, <tt>spherical</tt> if finite, <tt>cylindrical</tt> if 1D-periodic, <tt>planar</tt> if 2D-periodic,
337 !% <tt>fft_nocut</tt> if 3D-periodic.
338 !% See C. A. Rozzi et al., <i>Phys. Rev. B</i> <b>73</b>, 205119 (2006) for 3D implementation and
339 !% A. Castro et al., <i>Phys. Rev. B</i> <b>80</b>, 033102 (2009) for 2D implementation.
340 !%Option spherical 0
341 !% FFTs using spherical cutoff (in 2D or 3D).
342 !%Option cylindrical 1
343 !% FFTs using cylindrical cutoff (in 2D or 3D).
344 !%Option planar 2
345 !% FFTs using planar cutoff (in 3D).
346 !%Option fft_nocut 3
347 !% FFTs without using a cutoff (for fully periodic systems).
348 !%Option multipole_correction 4
349 !% The boundary conditions are imposed by using a multipole expansion. Only appropriate for finite systems.
350 !% Further specification occurs with variables <tt>PoissonSolverBoundaries</tt> and <tt>PoissonSolverMaxMultipole</tt>.
351 !%End
352
353 select case (space%dim)
354 case (1)
355 if (.not. space%is_periodic()) then
356 default_kernel = poisson_fft_kernel_sph
357 else
358 default_kernel = poisson_fft_kernel_nocut
359 end if
360 case (2)
361 if (space%periodic_dim == 2) then
362 default_kernel = poisson_fft_kernel_nocut
363 else if (space%is_periodic()) then
364 default_kernel = space%periodic_dim
365 else
366 default_kernel = poisson_fft_kernel_sph
367 end if
368 case (3)
369 default_kernel = space%periodic_dim
370 end select
371
372 call parse_variable(namespace, 'PoissonFFTKernel', default_kernel, this%kernel)
373 if (.not. varinfo_valid_option('PoissonFFTKernel', this%kernel)) call messages_input_error(namespace, 'PoissonFFTKernel')
374
375 if (optional_default(verbose,.true.)) then
376 call messages_print_var_option("PoissonFFTKernel", this%kernel, namespace=namespace)
377 end if
378
379 ! the multipole correction kernel does not work on GPUs
380 if(this%kernel == poisson_fft_kernel_corrected .and. fft_default_lib == fftlib_accel) then
382 message(1) = 'PoissonFFTKernel=multipole_correction is not supported on GPUs'
383 message(2) = 'Using FFTW to compute the FFTs on the CPU'
384 call messages_info(2, namespace=namespace)
385 end if
386
387 end if
388
389 !We assume the developer knows what he is doing by providing the solver option
390 if (.not. present(solver)) then
391 if (space%is_periodic() .and. this%method == poisson_direct_sum) then
392 message(1) = 'A periodic system may not use the direct_sum Poisson solver.'
393 call messages_fatal(1, namespace=namespace)
394 end if
395
396 if (space%is_periodic() .and. this%method == poisson_cg_corrected) then
397 message(1) = 'A periodic system may not use the cg_corrected Poisson solver.'
398 call messages_fatal(1, namespace=namespace)
399 end if
400
401 if (space%is_periodic() .and. this%method == poisson_cg) then
402 message(1) = 'A periodic system may not use the cg Poisson solver.'
403 call messages_fatal(1, namespace=namespace)
404 end if
405
406 if (space%is_periodic() .and. this%method == poisson_multigrid) then
407 message(1) = 'A periodic system may not use the multigrid Poisson solver.'
408 call messages_fatal(1, namespace=namespace)
409 end if
410
411 select case (space%dim)
412 case (1)
413
414 select case (space%periodic_dim)
415 case (0)
416 if ((this%method /= poisson_fft) .and. (this%method /= poisson_direct_sum)) then
417 message(1) = 'A finite 1D system may only use fft or direct_sum Poisson solvers.'
418 call messages_fatal(1, namespace=namespace)
419 end if
420 case (1)
421 if (this%method /= poisson_fft) then
422 message(1) = 'A periodic 1D system may only use the fft Poisson solver.'
423 call messages_fatal(1, namespace=namespace)
424 end if
425 end select
426
427 if (der%mesh%use_curvilinear .and. this%method /= poisson_direct_sum) then
428 message(1) = 'If curvilinear coordinates are used in 1D, then the only working'
429 message(2) = 'Poisson solver is direct_sum.'
430 call messages_fatal(2, namespace=namespace)
431 end if
432
433 case (2)
434
435 if ((this%method /= poisson_fft) .and. (this%method /= poisson_direct_sum)) then
436 message(1) = 'A 2D system may only use fft or direct_sum solvers.'
437 call messages_fatal(1, namespace=namespace)
438 end if
439
440 if (der%mesh%use_curvilinear .and. (this%method /= poisson_direct_sum)) then
441 message(1) = 'If curvilinear coordinates are used in 2D, then the only working'
442 message(2) = 'Poisson solver is direct_sum.'
443 call messages_fatal(2, namespace=namespace)
444 end if
445
446 case (3)
447
448 if (space%is_periodic() .and. this%method == poisson_isf) then
449 call messages_write('The ISF solver can only be used for finite systems.')
450 call messages_fatal()
451 end if
452
453 if (space%is_periodic() .and. this%method == poisson_fft .and. &
454 this%kernel /= space%periodic_dim .and. this%kernel >= 0 .and. this%kernel <= 3) then
455 write(message(1), '(a,i1,a)')'The system is periodic in ', space%periodic_dim ,' dimension(s),'
456 write(message(2), '(a,i1,a)')'but Poisson solver is set for ', this%kernel, ' dimensions.'
457 call messages_warning(2, namespace=namespace)
458 end if
459
460 if (space%is_periodic() .and. this%method == poisson_fft .and. this%kernel == poisson_fft_kernel_corrected) then
461 write(message(1), '(a,i1,a)')'PoissonFFTKernel = multipole_correction cannot be used for periodic systems.'
462 call messages_fatal(1, namespace=namespace)
463 end if
464
465 if (der%mesh%use_curvilinear .and. .not. any(this%method == [poisson_cg_corrected, poisson_multigrid])) then
466 message(1) = 'If curvilinear coordinates are used, then the only working'
467 message(2) = 'Poisson solver are cg_corrected and multigrid.'
468 call messages_fatal(2, namespace=namespace)
469 end if
470 if (der%mesh%use_curvilinear .and. this%method == poisson_multigrid .and. accel_is_enabled()) then
471 call messages_not_implemented('Multigrid Poisson solver with curvilinear coordinates on GPUs')
472 end if
473
474 select type (box => der%mesh%box)
475 type is (box_minimum_t)
476 if (this%method == poisson_cg_corrected) then
477 message(1) = 'When using the "minimum" box shape and the "cg_corrected"'
478 message(2) = 'Poisson solver, we have observed "sometimes" some non-'
479 message(3) = 'negligible error. You may want to check that the "fft" or "cg"'
480 message(4) = 'solver are providing, in your case, the same results.'
481 call messages_warning(4, namespace=namespace)
482 end if
483 end select
484
485 end select
486 end if
487
488 if (this%method == poisson_psolver) then
489#if !(defined HAVE_PSOLVER)
490 message(1) = "The PSolver Poisson solver cannot be used since the code was not compiled with the PSolver library."
491 call messages_fatal(1, namespace=namespace)
492#endif
493 end if
494
495 if (optional_default(verbose,.true.)) then
496 call messages_print_with_emphasis(namespace=namespace)
497 end if
498
499 ! Now that we know the method, we check if we need a cube and its dimentions
500 need_cube = .false.
501 fft_type = fft_real
502 if (optional_default(force_cmplx, .false.)) fft_type = fft_complex
503
504 if (this%method == poisson_isf .or. this%method == poisson_psolver) then
505 fft_type = fft_none
506 box(:) = der%mesh%idx%ll(:)
507 need_cube = .true.
508 end if
509
510 if (this%method == poisson_psolver .and. multicomm_have_slaves(mc)) then
511 call messages_not_implemented('Task parallelization with PSolver Poisson solver', namespace=namespace)
512 end if
513
515 ! Documentation in poisson_psolver.F90
516 call parse_variable(namespace, 'PoissonSolverPSolverParallelData', .true., isf_data_is_parallel)
517 if (this%method == poisson_psolver .and. isf_data_is_parallel) then
518 call messages_not_implemented("k-point parallelization with PSolver library and", namespace=namespace)
519 call messages_not_implemented("PoissonSolverPSolverParallelData = yes", namespace=namespace)
520 end if
521 if (this%method == poisson_fft .and. fft_library == fftlib_pfft) then
522 call messages_not_implemented("k-point parallelization with PFFT library for", namespace=namespace)
523 call messages_not_implemented("PFFT library for Poisson solver", namespace=namespace)
524 end if
525 end if
526
527 if (this%method == poisson_fft) then
528
529 need_cube = .true.
530
531 !%Variable DoubleFFTParameter
532 !%Type float
533 !%Default 2.0
534 !%Section Mesh::FFTs
535 !%Description
536 !% For solving the Poisson equation in Fourier space, and for applying the local potential
537 !% in Fourier space, an auxiliary cubic mesh is built. This mesh will be larger than
538 !% the circumscribed cube of the usual mesh by a factor <tt>DoubleFFTParameter</tt>. See
539 !% the section that refers to Poisson equation, and to the local potential for details
540 !% [the default value of two is typically good].
541 !%End
542 call parse_variable(namespace, 'DoubleFFTParameter', m_two, fft_alpha)
543 if (fft_alpha < m_one .or. fft_alpha > m_three) then
544 write(message(1), '(a,f12.5,a)') "Input: '", fft_alpha, &
545 "' is not a valid DoubleFFTParameter"
546 message(2) = '1.0 <= DoubleFFTParameter <= 3.0'
547 call messages_fatal(2, namespace=namespace)
548 end if
549
550 if (space%dim /= 3 .and. fft_library == fftlib_pfft) then
551 call messages_not_implemented('PFFT support for dimensionality other than 3', namespace=namespace)
552 end if
553
554 select case (space%dim)
555
556 case (1)
557 select case (this%kernel)
559 call mesh_double_box(space, der%mesh, fft_alpha, box)
561 box = der%mesh%idx%ll
562 end select
563
564 case (2)
565 select case (this%kernel)
567 call mesh_double_box(space, der%mesh, fft_alpha, box)
568 box(1:2) = maxval(box)
570 call mesh_double_box(space, der%mesh, fft_alpha, box)
572 box(:) = der%mesh%idx%ll(:)
573 end select
574
575 case (3)
576 select case (this%kernel)
578 call mesh_double_box(space, der%mesh, fft_alpha, box)
579 box(:) = maxval(box)
581 call mesh_double_box(space, der%mesh, fft_alpha, box)
582 box(2) = maxval(box(2:3)) ! max of finite directions
583 box(3) = maxval(box(2:3)) ! max of finite directions
585 box(:) = der%mesh%idx%ll(:)
587 call mesh_double_box(space, der%mesh, fft_alpha, box)
588 end select
589
590 end select
591
592 end if
593
594 ! Create the cube
595 if (need_cube) then
596 call cube_init(this%cube, box, namespace, space, der%mesh%spacing, &
597 der%mesh%coord_system, fft_type = fft_type, &
598 need_partition=.not.der%mesh%parallel_in_domains)
599 call cube_init_cube_map(this%cube, der%mesh)
600 if (this%cube%parallel_in_domains .and. this%method == poisson_fft) then
601 call mesh_cube_parallel_map_init(this%mesh_cube_map, der%mesh, this%cube)
602 end if
603 end if
604
605 if (this%is_dressed .and. .not. this%method == poisson_direct_sum) then
606 write(message(1), '(a)')'Dressed Orbital calculation currently only working with direct sum Poisson solver.'
607 call messages_fatal(1, namespace=namespace)
608 end if
609
610 call poisson_kernel_init(this, namespace, space, mc, stencil)
611
612 pop_sub(poisson_init)
613 end subroutine poisson_init
614
615 !-----------------------------------------------------------------
616 subroutine poisson_end(this)
617 type(poisson_t), intent(inout) :: this
618
619 logical :: has_cube
620
621 push_sub(poisson_end)
622
623 has_cube = .false.
624
625 select case (this%method)
626 case (poisson_fft)
627 call poisson_fft_end(this%fft_solver)
628 if (this%kernel == poisson_fft_kernel_corrected) call poisson_corrections_end(this%corrector)
629 has_cube = .true.
630
632 call poisson_cg_end()
633 call poisson_corrections_end(this%corrector)
634
635 case (poisson_multigrid)
636 call poisson_multigrid_end(this%mg)
637
638 case (poisson_isf)
639 call poisson_isf_end(this%isf_solver)
640 has_cube = .true.
641
642 case (poisson_psolver)
643 call poisson_psolver_end(this%psolver_solver)
644 has_cube = .true.
645
646 case (poisson_no)
647 call poisson_no_end(this%no_solver)
648
649 end select
650 this%method = poisson_null
651
652 if (has_cube) then
653 if (this%cube%parallel_in_domains) then
654 call mesh_cube_parallel_map_end(this%mesh_cube_map)
655 end if
656 call cube_end(this%cube)
657 end if
658
659 if (this%is_dressed) then
660 call photon_mode_end(this%photons)
661 end if
662 this%is_dressed = .false.
663
664 pop_sub(poisson_end)
665 end subroutine poisson_end
666
667 !-----------------------------------------------------------------
668
669 subroutine zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes, kernel)
670 type(poisson_t), intent(in) :: this
671 type(namespace_t), intent(in) :: namespace
672 complex(real64), contiguous, intent(inout) :: pot(:)
673 complex(real64), contiguous, intent(in) :: rho(:)
674 logical, optional, intent(in) :: all_nodes
675 type(fourier_space_op_t), optional, intent(in) :: kernel
676
677 real(real64), allocatable :: aux1(:), aux2(:)
678 type(derivatives_t), pointer :: der
679 logical :: all_nodes_value
680
681
682 der => this%der
683
685
686 call profiling_in('POISSON_RE_IM_SOLVE')
687
688 if (present(kernel)) then
689 assert(.not. any(abs(kernel%qq(:))>1e-8_real64))
690 end if
691
692 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
693
694 safe_allocate(aux1(1:der%mesh%np))
695 safe_allocate(aux2(1:der%mesh%np))
696 ! first the real part
697 aux1(1:der%mesh%np) = real(rho(1:der%mesh%np), real64)
698 aux2(1:der%mesh%np) = real(pot(1:der%mesh%np), real64)
699 call dpoisson_solve(this, namespace, aux2, aux1, all_nodes=all_nodes_value, kernel=kernel)
700 pot(1:der%mesh%np) = aux2(1:der%mesh%np)
701
702 ! now the imaginary part
703 aux1(1:der%mesh%np) = aimag(rho(1:der%mesh%np))
704 aux2(1:der%mesh%np) = aimag(pot(1:der%mesh%np))
705 call dpoisson_solve(this, namespace, aux2, aux1, all_nodes=all_nodes_value, kernel=kernel)
706 pot(1:der%mesh%np) = pot(1:der%mesh%np) + m_zi*aux2(1:der%mesh%np)
707
708 safe_deallocate_a(aux1)
709 safe_deallocate_a(aux2)
710
711 call profiling_out('POISSON_RE_IM_SOLVE')
712
715
716 !-----------------------------------------------------------------
717
718 subroutine zpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
719 type(poisson_t), intent(in) :: this
720 type(namespace_t), intent(in) :: namespace
721 complex(real64), contiguous, intent(inout) :: pot(:)
722 complex(real64), contiguous, intent(in) :: rho(:)
723 logical, optional, intent(in) :: all_nodes
724 type(fourier_space_op_t), optional, intent(in) :: kernel
725 logical, optional, intent(in) :: reset
726
727 logical :: all_nodes_value
728
729 push_sub(zpoisson_solve)
730
731 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
732
733 assert(ubound(pot, dim = 1) == this%der%mesh%np_part .or. ubound(pot, dim = 1) == this%der%mesh%np)
734 assert(ubound(rho, dim = 1) == this%der%mesh%np_part .or. ubound(rho, dim = 1) == this%der%mesh%np)
735
736 assert(this%method /= poisson_null)
737
738 if (poisson_solver_is_iterative(this) .and. optional_default(reset, .true.)) then
739 pot(1:this%der%mesh%np) = m_zero
740 end if
741
742 if (this%method == poisson_fft .and. this%kernel /= poisson_fft_kernel_corrected &
743 .and. .not. this%is_dressed) then
744 !The default (real) Poisson solver is used for OEP and Sternheimer calls were we do not need
745 !a complex-to-xomplex FFT as these parts use the normal Coulomb potential
746 if (this%cube%fft%type == fft_complex) then
747 !We add the profiling here, as the other path uses dpoisson_solve
748 call profiling_in('ZPOISSON_SOLVE')
749 call zpoisson_fft_solve(this%fft_solver, this%der%mesh, this%cube, pot, rho, this%mesh_cube_map, kernel=kernel)
750 call profiling_out('ZPOISSON_SOLVE')
751 else
752 call zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes_value, kernel=kernel)
753 end if
754 else
755 call zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes_value, kernel = kernel)
756 end if
757
758 pop_sub(zpoisson_solve)
759 end subroutine zpoisson_solve
760
761
762 !-----------------------------------------------------------------
763
764 subroutine poisson_solve_batch(this, namespace, potb, rhob, all_nodes, kernel)
765 type(poisson_t), intent(inout) :: this
766 type(namespace_t), intent(in) :: namespace
767 type(batch_t), intent(inout) :: potb
768 type(batch_t), intent(inout) :: rhob
769 logical, optional, intent(in) :: all_nodes
770 type(fourier_space_op_t), optional, intent(in) :: kernel
771
772 integer :: ii
773
774 push_sub(poisson_solve_batch)
775
776 assert(potb%nst_linear == rhob%nst_linear)
777 assert(potb%type() == rhob%type())
778
779 if (potb%type() == type_float) then
780 do ii = 1, potb%nst_linear
781 call dpoisson_solve(this, namespace, potb%dff_linear(:, ii), rhob%dff_linear(:, ii), all_nodes, kernel=kernel)
782 end do
783 else
784 do ii = 1, potb%nst_linear
785 call zpoisson_solve(this, namespace, potb%zff_linear(:, ii), rhob%zff_linear(:, ii), all_nodes, kernel=kernel)
786 end do
787 end if
788
789 pop_sub(poisson_solve_batch)
790 end subroutine poisson_solve_batch
791
792 !-----------------------------------------------------------------
793
799 subroutine dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
800 type(poisson_t), intent(in) :: this
801 type(namespace_t), intent(in) :: namespace
802 real(real64), contiguous, intent(inout) :: pot(:)
803 real(real64), contiguous, intent(in) :: rho(:)
807 logical, optional, intent(in) :: all_nodes
808 type(fourier_space_op_t), optional, intent(in) :: kernel
809 logical, optional, intent(in) :: reset
810
811 type(derivatives_t), pointer :: der
812 real(real64), allocatable :: rho_corrected(:), vh_correction(:)
813 logical :: all_nodes_value
814
815 call profiling_in('POISSON_SOLVE')
816 push_sub(dpoisson_solve)
817
818 der => this%der
819
820 assert(ubound(pot, dim = 1) == der%mesh%np_part .or. ubound(pot, dim = 1) == der%mesh%np)
821 assert(ubound(rho, dim = 1) == der%mesh%np_part .or. ubound(rho, dim = 1) == der%mesh%np)
822
823 ! Check optional argument and set to default if necessary.
824 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
825
826 if (poisson_solver_is_iterative(this) .and. optional_default(reset, .true.)) then
827 pot(1:der%mesh%np) = m_zero
828 end if
829
830 assert(this%method /= poisson_null)
831
832 if (present(kernel)) then
833 assert(this%method == poisson_fft)
834 end if
835
836 select case (this%method)
837 case (poisson_direct_sum)
838 if ((this%is_dressed .and. this%der%dim - 1 > 3) .or. this%der%dim > 3) then
839 message(1) = "Direct sum Poisson solver only available for 1, 2, or 3 dimensions."
840 call messages_fatal(1, namespace=namespace)
841 end if
842 call poisson_solve_direct(this, namespace, pot, rho)
843
844 case (poisson_cg)
845 call poisson_cg1(namespace, der, this%corrector, pot, rho)
846
848 safe_allocate(rho_corrected(1:der%mesh%np))
849 safe_allocate(vh_correction(1:der%mesh%np_part))
850
851 call correct_rho(this%corrector, der, rho, rho_corrected, vh_correction)
852
853 pot(1:der%mesh%np) = pot(1:der%mesh%np) - vh_correction(1:der%mesh%np)
854 call poisson_cg2(namespace, der, pot, rho_corrected)
855 pot(1:der%mesh%np) = pot(1:der%mesh%np) + vh_correction(1:der%mesh%np)
856
857 safe_deallocate_a(rho_corrected)
858 safe_deallocate_a(vh_correction)
859
860 case (poisson_multigrid)
861 call poisson_multigrid_solver(this%mg, namespace, der, pot, rho)
862
863 case (poisson_fft)
864 if (this%kernel /= poisson_fft_kernel_corrected) then
865 call dpoisson_fft_solve(this%fft_solver, der%mesh, this%cube, pot, rho, this%mesh_cube_map, kernel=kernel)
866 else
867 safe_allocate(rho_corrected(1:der%mesh%np))
868 safe_allocate(vh_correction(1:der%mesh%np_part))
869
870 call correct_rho(this%corrector, der, rho, rho_corrected, vh_correction)
871 call dpoisson_fft_solve(this%fft_solver, der%mesh, this%cube, pot, rho_corrected, this%mesh_cube_map, &
872 average_to_zero = .true., kernel=kernel)
873
874 pot(1:der%mesh%np) = pot(1:der%mesh%np) + vh_correction(1:der%mesh%np)
875 safe_deallocate_a(rho_corrected)
876 safe_deallocate_a(vh_correction)
877 end if
878
879 case (poisson_isf)
880 call poisson_isf_solve(this%isf_solver, der%mesh, this%cube, pot, rho, all_nodes_value)
881
882
883 case (poisson_psolver)
884 if (this%psolver_solver%datacode == "G") then
885 ! Global version
886 call poisson_psolver_global_solve(this%psolver_solver, der%mesh, this%cube, pot, rho)
887 else ! "D" Distributed version
888 call poisson_psolver_parallel_solve(this%psolver_solver, der%mesh, this%cube, pot, rho, this%mesh_cube_map)
889 end if
890
891 case (poisson_no)
892 call poisson_no_solve(this%no_solver, der%mesh, pot, rho)
893 end select
894
895
896 ! Add extra terms for dressed interaction
897 if (this%is_dressed .and. this%method /= poisson_no) then
898 call photon_mode_add_poisson_terms(this%photons, der%mesh, rho, pot)
899 end if
900
901 pop_sub(dpoisson_solve)
902 call profiling_out('POISSON_SOLVE')
903 end subroutine dpoisson_solve
904
905 !-----------------------------------------------------------------
906 subroutine poisson_init_sm(this, namespace, space, main, der, sm, method, force_cmplx)
907 type(poisson_t), intent(inout) :: this
908 type(namespace_t), intent(in) :: namespace
909 class(space_t), intent(in) :: space
910 type(poisson_t), intent(in) :: main
911 type(derivatives_t), target, intent(in) :: der
912 type(submesh_t), intent(inout) :: sm
913 integer, optional, intent(in) :: method
914 logical, optional, intent(in) :: force_cmplx
915
916 integer :: default_solver, idir, iter, maxl
917 integer :: box(space%dim)
918 real(real64) :: qq(der%dim), threshold
919
920 if (this%method /= poisson_null) return ! already initialized
921
922 push_sub(poisson_init_sm)
923
924 this%is_dressed = .false.
925 !TODO: To be implemented as an option
926 this%all_nodes_default = .false.
927
928 this%nslaves = 0
929 this%der => der
930
931#ifdef HAVE_MPI
932 this%all_nodes_default = main%all_nodes_default
933#endif
934
935 default_solver = poisson_direct_sum
936 this%method = default_solver
937 if (present(method)) this%method = method
938
939 if (der%mesh%use_curvilinear) then
940 call messages_not_implemented("Submesh Poisson solver with curvilinear mesh", namespace=namespace)
941 end if
942
943 this%kernel = poisson_fft_kernel_none
944
945 select case (this%method)
946 case (poisson_direct_sum)
947 !Nothing to be done
948
949 case (poisson_isf)
950 !TODO: Add support for domain parrallelization
951 assert(.not. der%mesh%parallel_in_domains)
952 call submesh_get_cube_dim(sm, space, box)
953 call submesh_init_cube_map(sm, space)
954 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
955 fft_type = fft_none, need_partition=.not.der%mesh%parallel_in_domains)
956 call cube_init_cube_map(this%cube, sm%mesh)
957 call poisson_isf_init(this%isf_solver, namespace, der%mesh, this%cube, mpi_world%comm, init_world = this%all_nodes_default)
958
959 case (poisson_psolver)
960 !TODO: Add support for domain parrallelization
961 assert(.not. der%mesh%parallel_in_domains)
962 if (this%all_nodes_default) then
963 this%cube%mpi_grp = mpi_world
964 else
965 this%cube%mpi_grp = this%der%mesh%mpi_grp
966 end if
967 call submesh_get_cube_dim(sm, space, box)
968 call submesh_init_cube_map(sm, space)
969 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
970 fft_type = fft_none, need_partition=.not.der%mesh%parallel_in_domains)
971 call cube_init_cube_map(this%cube, sm%mesh)
972 qq = m_zero
973 call poisson_psolver_init(this%psolver_solver, namespace, space, this%cube, m_zero, qq, force_isolated=.true.)
974 call poisson_psolver_get_dims(this%psolver_solver, this%cube)
975 case (poisson_fft)
976 !Here we impose zero boundary conditions
977 this%kernel = poisson_fft_kernel_sph
978 !We need to parse this, in case this routine is called before poisson_init
979 call parse_variable(namespace, 'FFTLibrary', fftlib_fftw, fft_default_lib)
980
981 call submesh_get_cube_dim(sm, space, box)
982 call submesh_init_cube_map(sm, space)
983 !We double the size of the cell
984 !Maybe the factor of two should be controlled as a variable
985 do idir = 1, space%dim
986 box(idir) = (2 * (box(idir) - 1)) + 1
987 end do
988 if (optional_default(force_cmplx, .false.)) then
989 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
990 fft_type = fft_complex, need_partition=.not.der%mesh%parallel_in_domains)
991 else
992 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
993 fft_type = fft_real, need_partition=.not.der%mesh%parallel_in_domains)
994 end if
995 call poisson_fft_init(this%fft_solver, namespace, space, this%cube, this%kernel)
996 case (poisson_cg)
997 call parse_variable(namespace, 'PoissonSolverMaxMultipole', 4, maxl)
998 write(message(1),'(a,i2)')'Info: Boundary conditions fixed up to L =', maxl
999 call messages_info(1, namespace=namespace)
1000 call parse_variable(namespace, 'PoissonSolverMaxIter', 500, iter)
1001 call parse_variable(namespace, 'PoissonSolverThreshold', 1.0e-6_real64, threshold)
1002 call poisson_corrections_init(this%corrector, namespace, space, maxl, this%der%mesh)
1003 call poisson_cg_init(threshold, iter)
1004 end select
1005
1006 pop_sub(poisson_init_sm)
1007 end subroutine poisson_init_sm
1008
1009 ! -----------------------------------------------------------------
1010
1011 logical pure function poisson_solver_is_iterative(this) result(iterative)
1012 type(poisson_t), intent(in) :: this
1013
1014 iterative = this%method == poisson_cg .or. this%method == poisson_cg_corrected
1015 end function poisson_solver_is_iterative
1016
1017 ! -----------------------------------------------------------------
1018
1019 logical pure function poisson_is_multigrid(this) result(is_multigrid)
1020 type(poisson_t), intent(in) :: this
1021
1022 is_multigrid = (this%method == poisson_multigrid)
1023
1024 end function poisson_is_multigrid
1025
1026 ! -----------------------------------------------------------------
1027
1028 logical pure function poisson_solver_has_free_bc(this) result(free_bc)
1029 type(poisson_t), intent(in) :: this
1030
1031 free_bc = .true.
1032
1033 if (this%method == poisson_fft .and. &
1034 this%kernel /= poisson_fft_kernel_sph .and. this%kernel /= poisson_fft_kernel_corrected) then
1035 free_bc = .false.
1036 end if
1037
1038 end function poisson_solver_has_free_bc
1039
1040 !-----------------------------------------------------------------
1041
1042 integer pure function poisson_get_solver(this) result (solver)
1043 type(poisson_t), intent(in) :: this
1044
1045 solver = this%method
1046 end function poisson_get_solver
1047
1048 !-----------------------------------------------------------------
1049
1050 subroutine poisson_async_init(this, mc)
1051 type(poisson_t), intent(inout) :: this
1052 type(multicomm_t), intent(in) :: mc
1053
1054 push_sub(poisson_async_init)
1055
1056#ifdef HAVE_MPI
1057 if (multicomm_have_slaves(mc)) then
1058
1059 call mpi_grp_init(this%local_grp, mc%group_comm(p_strategy_states))
1060
1061 this%root = (this%local_grp%rank == 0)
1062
1063 this%intercomm = mc%slave_intercomm
1064 call mpi_comm_remote_size(this%intercomm, this%nslaves, mpi_err)
1065
1066 end if
1067#endif
1068
1069 pop_sub(poisson_async_init)
1070
1071 end subroutine poisson_async_init
1072
1073 !-----------------------------------------------------------------
1074
1075 subroutine poisson_async_end(this, mc)
1076 type(poisson_t), intent(inout) :: this
1077 type(multicomm_t), intent(in) :: mc
1078
1079#ifdef HAVE_MPI
1080 integer :: islave
1081#endif
1082
1083 push_sub(poisson_async_end)
1084
1085#ifdef HAVE_MPI
1086 if (multicomm_have_slaves(mc)) then
1087
1088 ! send the finish signal
1089 do islave = this%local_grp%rank, this%nslaves - 1, this%local_grp%size
1090 call mpi_send(m_one, 1, mpi_double_precision, islave, cmd_finish, this%intercomm, mpi_err)
1091 end do
1092
1093 end if
1094#endif
1095
1096 pop_sub(poisson_async_end)
1097
1098 end subroutine poisson_async_end
1099
1100 !-----------------------------------------------------------------
1101
1102 subroutine poisson_slave_work(this, namespace)
1103 type(poisson_t), intent(inout) :: this
1104 type(namespace_t), intent(in) :: namespace
1105
1106#ifdef HAVE_MPI
1107 real(real64), allocatable :: rho(:), pot(:)
1108 logical :: done
1109 type(mpi_status) :: status
1110 integer :: bcast_root
1111
1113 call profiling_in("SLAVE_WORK")
1114
1115 safe_allocate(rho(1:this%der%mesh%np))
1116 safe_allocate(pot(1:this%der%mesh%np))
1117 done = .false.
1118
1119 do while(.not. done)
1120
1121 call profiling_in("SLAVE_WAIT")
1122 call mpi_recv(rho(1), this%der%mesh%np, mpi_double_precision, mpi_any_source, mpi_any_tag, this%intercomm, status, mpi_err)
1123 call profiling_out("SLAVE_WAIT")
1124
1125 ! The tag of the message tells us what we have to do.
1126 select case (status%MPI_TAG)
1127
1128 case (cmd_finish)
1129 done = .true.
1130
1131 case (cmd_poisson_solve)
1132 call dpoisson_solve(this, namespace, pot, rho)
1133
1134 call profiling_in("SLAVE_BROADCAST")
1135 bcast_root = mpi_proc_null
1136 if (this%root) bcast_root = mpi_root
1137 call mpi_bcast(pot(1), this%der%mesh%np, mpi_double_precision, bcast_root, this%intercomm, mpi_err)
1138 call profiling_out("SLAVE_BROADCAST")
1139
1140 end select
1141
1142 end do
1144 safe_deallocate_a(pot)
1145 safe_deallocate_a(rho)
1146
1147 call profiling_out("SLAVE_WORK")
1148 pop_sub(poisson_slave_work)
1149#endif
1150 end subroutine poisson_slave_work
1151
1152 !----------------------------------------------------------------
1153
1154 logical pure function poisson_is_async(this) result(async)
1155 type(poisson_t), intent(in) :: this
1156
1157 async = (this%nslaves > 0)
1158
1159 end function poisson_is_async
1160
1161 !----------------------------------------------------------------
1162
1163 subroutine poisson_build_kernel(this, namespace, space, coulb, qq, cam, singul)
1164 type(poisson_t), intent(in) :: this
1165 type(namespace_t), intent(in) :: namespace
1166 class(space_t), intent(in) :: space
1167 type(fourier_space_op_t), intent(inout) :: coulb
1168 real(real64), intent(in) :: qq(:)
1169 type(xc_cam_t), intent(in) :: cam
1170 real(real64), optional, intent(in) :: singul
1171
1172 real(real64), parameter :: vanishing_q = 1.0e-5_real64
1173 logical :: reinit
1174
1175 push_sub(poisson_build_kernel)
1176
1177 if (space%is_periodic()) then
1178 assert(ubound(qq, 1) >= space%periodic_dim)
1179 assert(this%method == poisson_fft)
1180 end if
1181
1182 if (cam%omega > m_epsilon) then
1183 if (this%method /= poisson_fft) then
1184 write(message(1),'(a)') "Poisson solver with range separation is only implemented with FFT."
1185 call messages_fatal(1, namespace=namespace)
1186 end if
1187 end if
1188
1189 !We only reinitialize the poisson solver if needed
1190 reinit = .false.
1191 if (allocated(coulb%qq)) then
1192 reinit = any(abs(coulb%qq(1:space%periodic_dim) - qq(1:space%periodic_dim)) > m_epsilon)
1193 end if
1194 reinit = reinit .or. (abs(coulb%mu - cam%omega) > m_epsilon .and. cam%omega > m_epsilon)
1195 reinit = reinit .or. (abs(coulb%alpha - cam%alpha) > m_epsilon .and. cam%alpha > m_epsilon)
1196 reinit = reinit .or. (abs(coulb%beta - cam%beta) > m_epsilon .and. cam%beta > m_epsilon)
1197
1198 if (reinit) then
1199 !TODO: this should be a select case supporting other kernels.
1200 ! This means that we need an abstract object for kernels.
1201 select case (this%method)
1202 case (poisson_fft)
1203 ! Check that we are consistent: the Poisson solver supports must return 1 here
1204 assert(is_close(poisson_get_full_range_weight(this, cam), m_one))
1205
1206 call fourier_space_op_end(coulb)
1207
1208 safe_allocate(coulb%qq(1:space%dim))
1209 coulb%qq(1:space%periodic_dim) = qq(1:space%periodic_dim)
1210 coulb%qq(space%periodic_dim+1:space%dim) = vanishing_q
1211 !We must define the singularity if we specify a q vector and we do not use the short-range Coulomb potential
1212 coulb%singularity = optional_default(singul, m_zero)
1213 coulb%mu = cam%omega
1214 coulb%alpha = cam%alpha
1215 coulb%beta = cam%beta
1216 call poisson_fft_get_kernel(namespace, space, this%cube, coulb, this%kernel, &
1217 this%poisson_soft_coulomb_param)
1218 case default
1219 call messages_not_implemented("poisson_build_kernel with other methods than FFT", namespace=namespace)
1220 end select
1221 end if
1222
1223 pop_sub(poisson_build_kernel)
1224 end subroutine poisson_build_kernel
1225
1226 !----------------------------------------------------------------
1235 real(real64) function poisson_get_full_range_weight(this, cam) result(weight)
1236 type(poisson_t), intent(in) :: this
1237 type(xc_cam_t), intent(in) :: cam
1238
1239 select case (this%method)
1240 case (poisson_fft)
1241 weight = m_one
1242 case default
1243 if(cam%omega < m_epsilon) then
1244 weight = cam%alpha
1245 else if(cam%alpha > m_epsilon .and. cam%beta < m_epsilon) then
1246 weight = cam%alpha
1247 else if(cam%alpha < m_epsilon .and. cam%beta > m_epsilon) then
1248 weight = cam%beta
1249 else
1250 assert(.false.)
1251 end if
1252 end select
1254
1255#include "poisson_init_inc.F90"
1256#include "poisson_direct_inc.F90"
1257#include "poisson_direct_sm_inc.F90"
1258
1259#include "undef.F90"
1260#include "real.F90"
1261#include "poisson_inc.F90"
1262#include "undef.F90"
1263#include "complex.F90"
1264#include "poisson_inc.F90"
1265
1266end module poisson_oct_m
1267
1268!! Local Variables:
1269!! mode: f90
1270!! coding: utf-8
1271!! End:
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:180
pure logical function, public accel_is_enabled()
Definition: accel.F90:427
This module implements batches of mesh functions.
Definition: batch.F90:133
This module handles the calculation mode.
integer, parameter, public p_strategy_kpoints
parallelization in k-points
subroutine, public cube_init(cube, nn, namespace, space, spacing, coord_system, fft_type, fft_library, dont_optimize, nn_out, mpi_grp, need_partition, tp_enlarge, blocksize)
Definition: cube.F90:202
subroutine, public cube_end(cube)
Definition: cube.F90:378
subroutine, public cube_init_cube_map(cube, mesh)
Definition: cube.F90:823
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
Definition: fft.F90:118
integer, parameter, public fft_none
global constants
Definition: fft.F90:178
integer, public fft_default_lib
Definition: fft.F90:259
integer, parameter, public fftlib_accel
Definition: fft.F90:183
integer, parameter, public fft_real
Definition: fft.F90:178
integer, parameter, public fft_complex
Definition: fft.F90:178
integer, parameter, public fftlib_pfft
Definition: fft.F90:183
integer, parameter, public fftlib_fftw
Definition: fft.F90:183
real(real64), parameter, public m_two
Definition: global.F90:190
real(real64), parameter, public m_zero
Definition: global.F90:188
complex(real64), parameter, public m_zi
Definition: global.F90:202
real(real64), parameter, public m_one
Definition: global.F90:189
real(real64), parameter, public m_three
Definition: global.F90:191
This module implements the index, used for the mesh points.
Definition: index.F90:122
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
subroutine, public mesh_cube_parallel_map_end(this)
subroutine, public mesh_cube_parallel_map_init(this, mesh, cube)
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public mesh_double_box(space, mesh, alpha, db)
finds the dimension of a box doubled in the non-periodic dimensions
Definition: mesh.F90:281
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:920
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1113
character(len=512), private msg
Definition: messages.F90:165
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:537
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:414
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:713
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1085
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:616
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:270
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:145
logical pure function, public multicomm_strategy_is_parallel(mc, level)
Definition: multicomm.F90:925
logical pure function, public multicomm_have_slaves(this)
Definition: multicomm.F90:1141
Some general things and nomenclature:
Definition: par_vec.F90:171
subroutine, public photon_mode_compute_dipoles(this, mesh)
Computes the polarization dipole.
subroutine, public photon_mode_add_poisson_terms(this, mesh, rho, pot)
subroutine, public photon_mode_end(this)
subroutine, public photon_mode_set_n_electrons(this, qtot)
subroutine, public photon_mode_init(this, namespace, dim, photon_free)
real(real64), public threshold
Definition: poisson_cg.F90:136
subroutine, public poisson_cg2(namespace, der, pot, rho)
Definition: poisson_cg.F90:211
subroutine, public poisson_cg1(namespace, der, corrector, pot, rho)
Definition: poisson_cg.F90:162
subroutine, public poisson_cg_init(thr, itr)
Definition: poisson_cg.F90:144
subroutine, public poisson_cg_end
Definition: poisson_cg.F90:156
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)
integer, parameter, public poisson_fft_kernel_nocut
integer, parameter, public poisson_fft_kernel_cyl
subroutine, public zpoisson_fft_solve(this, mesh, cube, pot, rho, mesh_cube_map, average_to_zero, kernel, sm)
subroutine, public poisson_fft_end(this)
subroutine, public poisson_fft_init(this, namespace, space, cube, kernel, soft_coulb_param, fullcube)
integer, parameter, public poisson_fft_kernel_pla
integer, parameter, public poisson_fft_kernel_none
integer, parameter, public poisson_fft_kernel_corrected
integer, parameter, public poisson_fft_kernel_sph
subroutine, public dpoisson_fft_solve(this, mesh, cube, pot, rho, mesh_cube_map, average_to_zero, kernel, sm)
subroutine, public poisson_isf_end(this)
subroutine, public poisson_isf_init(this, namespace, mesh, cube, all_nodes_comm, init_world)
subroutine, public poisson_isf_solve(this, mesh, cube, pot, rho, all_nodes, sm)
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_no_solve(this, mesh, pot, rho)
Definition: poisson_no.F90:163
subroutine, public poisson_no_end(this)
Definition: poisson_no.F90:151
subroutine, public zpoisson_solve_sm(this, namespace, sm, pot, rho, all_nodes)
Calculates the Poisson equation. Given the density returns the corresponding potential.
Definition: poisson.F90:2346
integer, parameter, public poisson_multigrid
Definition: poisson.F90:190
subroutine poisson_kernel_init(this, namespace, space, mc, stencil)
Definition: poisson.F90:1369
integer, parameter, public poisson_psolver
Definition: poisson.F90:190
subroutine, public dpoisson_solve_start(this, rho)
Definition: poisson.F90:2115
integer, parameter cmd_finish
Definition: poisson.F90:226
subroutine, public zpoisson_solve_finish(this, pot)
Definition: poisson.F90:2323
subroutine poisson_solve_direct(this, namespace, pot, rho)
Definition: poisson.F90:1573
integer, parameter, public poisson_fft
Definition: poisson.F90:190
logical pure function, public poisson_is_multigrid(this)
Definition: poisson.F90:1113
subroutine, public zpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Definition: poisson.F90:812
subroutine, public poisson_solve_batch(this, namespace, potb, rhob, all_nodes, kernel)
Definition: poisson.F90:858
subroutine, public poisson_async_init(this, mc)
Definition: poisson.F90:1144
subroutine, public dpoisson_solve_sm(this, namespace, sm, pot, rho, all_nodes)
Calculates the Poisson equation. Given the density returns the corresponding potential.
Definition: poisson.F90:2161
subroutine zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes, kernel)
Definition: poisson.F90:763
subroutine, public poisson_init_sm(this, namespace, space, main, der, sm, method, force_cmplx)
Definition: poisson.F90:1000
logical pure function poisson_solver_is_iterative(this)
Definition: poisson.F90:1105
subroutine, public poisson_slave_work(this, namespace)
Definition: poisson.F90:1196
subroutine, public dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Calculates the Poisson equation. Given the density returns the corresponding potential.
Definition: poisson.F90:893
integer, parameter cmd_poisson_solve
Definition: poisson.F90:226
integer, parameter, public poisson_cg
Definition: poisson.F90:190
subroutine, public poisson_build_kernel(this, namespace, space, coulb, qq, cam, singul)
Definition: poisson.F90:1257
logical pure function, public poisson_solver_has_free_bc(this)
Definition: poisson.F90:1122
subroutine, public dpoisson_solve_finish(this, pot)
Definition: poisson.F90:2138
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx)
Definition: poisson.F90:234
subroutine, public zpoisson_solve_start(this, rho)
Definition: poisson.F90:2300
subroutine, public poisson_async_end(this, mc)
Definition: poisson.F90:1169
integer, parameter, public poisson_cg_corrected
Definition: poisson.F90:190
integer pure function, public poisson_get_solver(this)
Definition: poisson.F90:1136
integer, parameter, public poisson_isf
Definition: poisson.F90:190
real(real64) function, public poisson_get_full_range_weight(this, cam)
Most Poisson solvers do not implement Coulomb attenuated potentials, and can only be used for global ...
Definition: poisson.F90:1329
integer, parameter, public poisson_null
Definition: poisson.F90:190
integer, parameter, public poisson_no
Definition: poisson.F90:190
logical pure function, public poisson_is_async(this)
Definition: poisson.F90:1248
subroutine, public poisson_end(this)
Definition: poisson.F90:710
subroutine, public poisson_psolver_global_solve(this, mesh, cube, pot, rho, sm)
subroutine, public poisson_psolver_parallel_solve(this, mesh, cube, pot, rho, mesh_cube_map)
subroutine, public poisson_psolver_end(this)
subroutine, public poisson_psolver_get_dims(this, cube)
subroutine, public poisson_psolver_init(this, namespace, space, cube, mu, qq, force_isolated)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:623
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:552
This module defines stencils used in Octopus.
Definition: stencil.F90:135
subroutine, public submesh_init_cube_map(sm, space)
Definition: submesh.F90:1007
subroutine, public submesh_get_cube_dim(sm, space, db)
finds the dimension of a box containing the submesh
Definition: submesh.F90:972
type(type_t), public type_float
Definition: types.F90:133
This module defines the unit system, used for input and output.
Class defining batches of mesh functions.
Definition: batch.F90:159
Class implementing a box that is a union of spheres. We do this in a specific class instead of using ...
class representing derivatives
A submesh is a type of mesh, used for the projectors in the pseudopotentials It contains points on a ...
Definition: submesh.F90:175
int true(void)