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 cube_oct_m
29 use debug_oct_m
31 use fft_oct_m
33 use global_oct_m
34 use index_oct_m
35 use, intrinsic :: iso_fortran_env
38 use math_oct_m
39 use mesh_oct_m
43 use mpi_oct_m
46#ifdef HAVE_OPENMP
47 use omp_lib
48#endif
50 use parser_oct_m
61 use space_oct_m
64 use types_oct_m
67 use xc_cam_oct_m
68
69 implicit none
70
71 private
72 public :: &
73 poisson_t, &
100
101 integer, public, parameter :: &
102 POISSON_DIRECT_SUM = -1, &
103 poisson_fft = 0, &
104 poisson_cg = 5, &
106 poisson_multigrid = 7, &
107 poisson_isf = 8, &
108 poisson_psolver = 10, &
109 poisson_no = -99, &
110 poisson_null = -999
111
112 type poisson_t
113 private
114 type(derivatives_t), pointer, public :: der
115 integer, public :: method = poisson_null
116 integer, public :: kernel
117 type(cube_t), public :: cube
118 type(mesh_cube_parallel_map_t), public :: mesh_cube_map
119 type(poisson_mg_solver_t) :: mg
120 type(poisson_fft_t), public :: fft_solver
121 real(real64), public :: poisson_soft_coulomb_param
122 logical :: all_nodes_default
123 type(poisson_corr_t) :: corrector
124 type(poisson_isf_t) :: isf_solver
125 type(poisson_psolver_t) :: psolver_solver
126 type(poisson_no_t) :: no_solver
127 integer :: nslaves
128 logical, public :: is_dressed = .false.
129 type(photon_mode_t), public :: photons
130#ifdef HAVE_MPI
131 type(MPI_Comm) :: intercomm
132 type(mpi_grp_t) :: local_grp
133 logical :: root
134#endif
135 end type poisson_t
136
137 integer, parameter :: &
138 CMD_FINISH = 1, &
140
141contains
142
143 !-----------------------------------------------------------------
144 subroutine poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, &
145 force_cmplx, fft_batch_size, single_precision)
146 type(poisson_t), intent(inout) :: this
147 class(space_t), intent(in) :: space
148 type(namespace_t), intent(in) :: namespace
149 type(derivatives_t), target, intent(in) :: der
150 type(multicomm_t), intent(in) :: mc
151 type(stencil_t), intent(in) :: stencil
152 real(real64), optional, intent(in) :: qtot
153 character(len=*), optional, intent(in) :: label
154 integer, optional, intent(in) :: solver
155 logical, optional, intent(in) :: verbose
156 logical, optional, intent(in) :: force_serial
157 logical, optional, intent(in) :: force_cmplx
158 integer, optional, intent(in) :: fft_batch_size
159 logical, optional, intent(in) :: single_precision
160
161 logical :: need_cube, isf_data_is_parallel
162 integer :: default_solver, default_kernel, box(space%dim), fft_type, fft_library, fft_bs
163 real(real64) :: fft_alpha
164 character(len=60) :: str
165
166 ! Make sure we do not try to initialize an already initialized solver
167 assert(this%method == poisson_null)
168
169 push_sub(poisson_init)
170
171 if (optional_default(verbose,.true.)) then
172 str = "Hartree"
173 if (present(label)) str = trim(label)
174 call messages_print_with_emphasis(msg=trim(str), namespace=namespace)
175 end if
176
177 this%nslaves = 0
178 this%der => der
179
180 !%Variable DressedOrbitals
181 !%Type logical
182 !%Default false
183 !%Section Hamiltonian::Poisson
184 !%Description
185 !% Allows for the calculation of coupled elecron-photon problems
186 !% by applying the dressed orbital approach. Details can be found in
187 !% https://arxiv.org/abs/1812.05562
188 !% At the moment, N electrons in d (<=3) spatial dimensions, coupled
189 !% to one photon mode can be described. The photon mode is included by
190 !% raising the orbital dimension to d+1 and changing the particle interaction
191 !% kernel and the local potential, where the former is included automatically,
192 !% but the latter needs to by added by hand as a user_defined_potential!
193 !% Coordinate 1-d: electron; coordinate d+1: photon.
194 !%End
195 call parse_variable(namespace, 'DressedOrbitals', .false., this%is_dressed)
196 call messages_print_var_value('DressedOrbitals', this%is_dressed, namespace=namespace)
197 if (this%is_dressed) then
198 assert(present(qtot))
199 call messages_experimental('Dressed Orbitals', namespace=namespace)
200 assert(qtot > m_zero)
201 call photon_mode_init(this%photons, namespace, der%dim-1)
202 call photon_mode_set_n_electrons(this%photons, qtot)
203 if(.not.allocated(this%photons%pol_dipole)) then
204 call photon_mode_compute_dipoles(this%photons, der%mesh)
205 end if
206 if (this%photons%nmodes > 1) then
207 call messages_not_implemented('DressedOrbitals for more than one photon mode', namespace=namespace)
208 end if
209 end if
211 this%all_nodes_default = .false.
212#ifdef HAVE_MPI
213 if (.not. optional_default(force_serial, .false.)) then
214 !%Variable ParallelizationPoissonAllNodes
215 !%Type logical
216 !%Default true
217 !%Section Execution::Parallelization
218 !%Description
219 !% When running in parallel, this variable selects whether the
220 !% Poisson solver should divide the work among all nodes or only
221 !% among the parallelization-in-domains groups.
222 !%End
224 call parse_variable(namespace, 'ParallelizationPoissonAllNodes', .true., this%all_nodes_default)
225 end if
226#endif
227
228 !%Variable PoissonSolver
229 !%Type integer
230 !%Section Hamiltonian::Poisson
231 !%Description
232 !% Defines which method to use to solve the Poisson equation. Some incompatibilities apply depending on
233 !% dimensionality, periodicity, etc.
234 !% For a comparison of the accuracy and performance of the methods in Octopus, see P Garcia-Risue&ntilde;o,
235 !% J Alberdi-Rodriguez <i>et al.</i>, <i>J. Comp. Chem.</i> <b>35</b>, 427-444 (2014)
236 !% or <a href=http://arxiv.org/abs/1211.2092>arXiV</a>.
237 !% Defaults:
238 !% <br> 1D and 2D: <tt>fft</tt>.
239 !% <br> 3D: <tt>cg_corrected</tt> if curvilinear, <tt>isf</tt> if not periodic, <tt>fft</tt> if periodic.
240 !% <br> Dressed orbitals: <tt>direct_sum</tt>.
241 !%Option NoPoisson -99
242 !% Do not use a Poisson solver at all.
243 !%Option direct_sum -1
244 !% Direct evaluation of the Hartree potential (only for finite systems).
245 !%Option fft 0
246 !% The Poisson equation is solved using FFTs. A cutoff technique
247 !% for the Poisson kernel is selected so the proper boundary
248 !% conditions are imposed according to the periodicity of the
249 !% system. This can be overridden by the <tt>PoissonFFTKernel</tt>
250 !% variable. To choose the FFT library use <tt>FFTLibrary</tt>
251 !%Option cg 5
252 !% Conjugate gradients.
253 !%Option cg_corrected 6
254 !% Conjugate gradients, corrected for boundary conditions (only for finite systems).
255 !%Option multigrid 7
256 !% Multigrid method.
257 !%Option isf 8
258 !% Interpolating Scaling Functions Poisson solver (only for finite systems).
259 !%Option psolver 10
260 !% Solver based on Interpolating Scaling Functions as implemented in the PSolver library.
261 !% Parallelization in k-points requires <tt>PoissonSolverPSolverParallelData</tt> = no.
262 !% Requires the PSolver external library.
263 !%End
264
265 default_solver = poisson_fft
266
267 if (space%dim == 3 .and. .not. space%is_periodic()) default_solver = poisson_isf
268
269#ifdef HAVE_CUDA
270 if(accel_is_enabled()) default_solver = poisson_fft
271#endif
272
273 if (space%dim > 3) default_solver = poisson_no ! Kernel for higher dimensions is not implemented.
274
275 if (der%mesh%use_curvilinear) then
276 select case (space%dim)
277 case (1)
278 default_solver = poisson_direct_sum
279 case (2)
280 default_solver = poisson_direct_sum
281 case (3)
282 default_solver = poisson_multigrid
283 end select
284 end if
285
286 if (this%is_dressed) default_solver = poisson_direct_sum
287
288 if (.not. present(solver)) then
289 call parse_variable(namespace, 'PoissonSolver', default_solver, this%method)
290 else
291 this%method = solver
292 end if
293 if (.not. varinfo_valid_option('PoissonSolver', this%method)) call messages_input_error(namespace, 'PoissonSolver')
294 if (optional_default(verbose, .true.)) then
295 select case (this%method)
296 case (poisson_direct_sum)
297 str = "direct sum"
298 case (poisson_fft)
299 str = "fast Fourier transform"
300 case (poisson_cg)
301 str = "conjugate gradients"
303 str = "conjugate gradients, corrected"
304 case (poisson_multigrid)
305 str = "multigrid"
306 case (poisson_isf)
307 str = "interpolating scaling functions"
308 case (poisson_psolver)
309 str = "interpolating scaling functions (from BigDFT)"
310 case (poisson_no)
311 str = "no Poisson solver - Hartree set to 0"
312 end select
313 write(message(1),'(a,a,a)') "The chosen Poisson solver is '", trim(str), "'"
314 call messages_info(1, namespace=namespace)
315 end if
316
317 if (space%dim > 3 .and. this%method /= poisson_no) then
318 call messages_input_error(namespace, 'PoissonSolver', 'Currently no Poisson solver is available for Dimensions > 3')
319 end if
320
321 fft_bs = optional_default(fft_batch_size, 1)
322 assert(fft_bs > 0)
323
324 if (this%method /= poisson_fft) then
325 this%kernel = poisson_fft_kernel_none
326 else
327
328 ! Documentation in cube.F90
329 call parse_variable(namespace, 'FFTLibrary', fftlib_fftw, fft_library)
330
331 !%Variable PoissonFFTKernel
332 !%Type integer
333 !%Section Hamiltonian::Poisson
334 !%Description
335 !% Defines which kernel is used to impose the correct boundary
336 !% conditions when using FFTs to solve the Poisson equation. The
337 !% default is selected depending on the dimensionality and
338 !% periodicity of the system:
339 !% <br>In 1D, <tt>spherical</tt> if finite, <tt>fft_nocut</tt> if periodic.
340 !% <br>In 2D, <tt>spherical</tt> if finite, <tt>cylindrical</tt> if 1D-periodic, <tt>fft_nocut</tt> if 2D-periodic.
341 !% <br>In 3D, <tt>spherical</tt> if finite, <tt>cylindrical</tt> if 1D-periodic, <tt>planar</tt> if 2D-periodic,
342 !% <tt>fft_nocut</tt> if 3D-periodic.
343 !% See C. A. Rozzi et al., <i>Phys. Rev. B</i> <b>73</b>, 205119 (2006) for 3D implementation and
344 !% A. Castro et al., <i>Phys. Rev. B</i> <b>80</b>, 033102 (2009) for 2D implementation.
345 !%Option spherical 0
346 !% FFTs using spherical cutoff (in 2D or 3D).
347 !%Option cylindrical 1
348 !% FFTs using cylindrical cutoff (in 2D or 3D).
349 !%Option planar 2
350 !% FFTs using planar cutoff (in 3D).
351 !%Option fft_nocut 3
352 !% FFTs without using a cutoff (for fully periodic systems).
353 !%Option multipole_correction 4
354 !% The boundary conditions are imposed by using a multipole expansion. Only appropriate for finite systems.
355 !% Further specification occurs with variables <tt>PoissonSolverBoundaries</tt> and <tt>PoissonSolverMaxMultipole</tt>.
356 !%End
357
358 select case (space%dim)
359 case (1)
360 if (.not. space%is_periodic()) then
361 default_kernel = poisson_fft_kernel_sph
362 else
363 default_kernel = poisson_fft_kernel_nocut
364 end if
365 case (2)
366 if (space%periodic_dim == 2) then
367 default_kernel = poisson_fft_kernel_nocut
368 else if (space%is_periodic()) then
369 default_kernel = space%periodic_dim
370 else
371 default_kernel = poisson_fft_kernel_sph
372 end if
373 case (3)
374 default_kernel = space%periodic_dim
375 end select
376
377 call parse_variable(namespace, 'PoissonFFTKernel', default_kernel, this%kernel)
378 if (.not. varinfo_valid_option('PoissonFFTKernel', this%kernel)) call messages_input_error(namespace, 'PoissonFFTKernel')
379
380 if (optional_default(verbose,.true.)) then
381 call messages_print_var_option("PoissonFFTKernel", this%kernel, namespace=namespace)
382 end if
383
384 ! the multipole correction kernel does not work on GPUs
385 if(this%kernel == poisson_fft_kernel_corrected .and. fft_default_lib == fftlib_accel) then
387 message(1) = 'PoissonFFTKernel=multipole_correction is not supported on GPUs'
388 message(2) = 'Using FFTW to compute the FFTs on the CPU'
389 call messages_info(2, namespace=namespace)
390 end if
391
392 end if
393
394 !We assume the developer knows what he is doing by providing the solver option
395 if (.not. present(solver)) then
396 if (space%is_periodic() .and. this%method == poisson_direct_sum) then
397 message(1) = 'A periodic system may not use the direct_sum Poisson solver.'
398 call messages_fatal(1, namespace=namespace)
399 end if
400
401 if (space%is_periodic() .and. this%method == poisson_cg_corrected) then
402 message(1) = 'A periodic system may not use the cg_corrected Poisson solver.'
403 call messages_fatal(1, namespace=namespace)
404 end if
405
406 select case (space%dim)
407 case (1)
408
409 select case (space%periodic_dim)
410 case (0)
411 if ((this%method /= poisson_fft) .and. (this%method /= poisson_direct_sum)) then
412 message(1) = 'A finite 1D system may only use fft or direct_sum Poisson solvers.'
413 call messages_fatal(1, namespace=namespace)
414 end if
415 case (1)
416 if (this%method /= poisson_fft) then
417 message(1) = 'A periodic 1D system may only use the fft Poisson solver.'
418 call messages_fatal(1, namespace=namespace)
419 end if
420 end select
421
422 if (der%mesh%use_curvilinear .and. this%method /= poisson_direct_sum) then
423 message(1) = 'If curvilinear coordinates are used in 1D, then the only working'
424 message(2) = 'Poisson solver is direct_sum.'
425 call messages_fatal(2, namespace=namespace)
426 end if
427
428 case (2)
429
430 if ((this%method /= poisson_fft) .and. (this%method /= poisson_direct_sum)) then
431 message(1) = 'A 2D system may only use fft or direct_sum solvers.'
432 call messages_fatal(1, namespace=namespace)
433 end if
434
435 if (der%mesh%use_curvilinear .and. (this%method /= poisson_direct_sum)) then
436 message(1) = 'If curvilinear coordinates are used in 2D, then the only working'
437 message(2) = 'Poisson solver is direct_sum.'
438 call messages_fatal(2, namespace=namespace)
439 end if
440
441 case (3)
442
443 if (space%is_periodic() .and. this%method == poisson_isf) then
444 call messages_write('The ISF solver can only be used for finite systems.')
445 call messages_fatal()
446 end if
447
448 if (space%is_periodic() .and. this%method == poisson_fft .and. &
449 this%kernel /= space%periodic_dim .and. this%kernel >= 0 .and. this%kernel <= 3) then
450 write(message(1), '(a,i1,a)')'The system is periodic in ', space%periodic_dim ,' dimension(s),'
451 write(message(2), '(a,i1,a)')'but Poisson solver is set for ', this%kernel, ' dimensions.'
452 call messages_warning(2, namespace=namespace)
453 end if
454
455 if (space%is_periodic() .and. this%method == poisson_fft .and. this%kernel == poisson_fft_kernel_corrected) then
456 write(message(1), '(a,i1,a)')'PoissonFFTKernel = multipole_correction cannot be used for periodic systems.'
457 call messages_fatal(1, namespace=namespace)
458 end if
459
460 if (der%mesh%use_curvilinear .and. .not. any(this%method == [poisson_cg_corrected, poisson_multigrid])) then
461 message(1) = 'If curvilinear coordinates are used, then the only working'
462 message(2) = 'Poisson solvers are cg_corrected and multigrid.'
463 call messages_fatal(2, namespace=namespace)
464 end if
465 if (der%mesh%use_curvilinear .and. this%method == poisson_multigrid .and. accel_is_enabled()) then
466 call messages_not_implemented('Multigrid Poisson solver with curvilinear coordinates on GPUs')
467 end if
468
469 select type (box => der%mesh%box)
470 type is (box_minimum_t)
471 if (this%method == poisson_cg_corrected) then
472 message(1) = 'When using the "minimum" box shape and the "cg_corrected"'
473 message(2) = 'Poisson solver, we have observed "sometimes" some non-'
474 message(3) = 'negligible error. You may want to check that the "fft" or "cg"'
475 message(4) = 'solver are providing, in your case, the same results.'
476 call messages_warning(4, namespace=namespace)
477 end if
478 end select
479
480 end select
481 end if
482
483 if (this%method == poisson_psolver) then
484#if !(defined HAVE_PSOLVER)
485 message(1) = "The PSolver Poisson solver cannot be used since the code was not compiled with the PSolver library."
486 call messages_fatal(1, namespace=namespace)
487#endif
488 end if
489
490 if (optional_default(verbose,.true.)) then
491 call messages_print_with_emphasis(namespace=namespace)
492 end if
493
494 ! Now that we know the method, we check if we need a cube and its dimensions
495 need_cube = .false.
496 fft_type = fft_real
497 if (optional_default(force_cmplx, .false.)) fft_type = fft_complex
498
499 if (this%method == poisson_isf .or. this%method == poisson_psolver) then
500 fft_type = fft_none
501 box(:) = der%mesh%idx%ll(:)
502 need_cube = .true.
503 end if
504
505 if (this%method == poisson_psolver .and. multicomm_have_slaves(mc)) then
506 call messages_not_implemented('Task parallelization with PSolver Poisson solver', namespace=namespace)
507 end if
508
510 ! Documentation in poisson_psolver.F90
511 call parse_variable(namespace, 'PoissonSolverPSolverParallelData', .true., isf_data_is_parallel)
512 if (this%method == poisson_psolver .and. isf_data_is_parallel) then
513 call messages_not_implemented("k-point parallelization with PSolver library and", namespace=namespace)
514 call messages_not_implemented("PoissonSolverPSolverParallelData = yes", namespace=namespace)
515 end if
516 if (this%method == poisson_fft .and. fft_library == fftlib_pfft) then
517 call messages_not_implemented("k-point parallelization with PFFT library for", namespace=namespace)
518 call messages_not_implemented("PFFT library for Poisson solver", namespace=namespace)
519 end if
520 end if
521
522 if (this%method == poisson_fft) then
523
524 need_cube = .true.
525
526 !%Variable DoubleFFTParameter
527 !%Type float
528 !%Default 2.0
529 !%Section Mesh::FFTs
530 !%Description
531 !% For solving the Poisson equation in Fourier space, and for applying the local potential
532 !% in Fourier space, an auxiliary cubic mesh is built. This mesh will be larger than
533 !% the circumscribed cube of the usual mesh by a factor <tt>DoubleFFTParameter</tt>. See
534 !% the section that refers to Poisson equation, and to the local potential for details
535 !% [the default value of two is typically good].
536 !%End
537 call parse_variable(namespace, 'DoubleFFTParameter', m_two, fft_alpha)
538 if (fft_alpha < m_one .or. fft_alpha > m_three) then
539 write(message(1), '(a,f12.5,a)') "Input: '", fft_alpha, &
540 "' is not a valid DoubleFFTParameter"
541 message(2) = '1.0 <= DoubleFFTParameter <= 3.0'
542 call messages_fatal(2, namespace=namespace)
543 end if
544
545 if (space%dim /= 3 .and. fft_library == fftlib_pfft) then
546 call messages_not_implemented('PFFT support for dimensionality other than 3', namespace=namespace)
547 end if
548
549 select case (space%dim)
550
551 case (1)
552 select case (this%kernel)
554 call mesh_double_box(space, der%mesh, fft_alpha, box)
556 box = der%mesh%idx%ll
557 end select
558
559 case (2)
560 select case (this%kernel)
562 call mesh_double_box(space, der%mesh, fft_alpha, box)
563 box(1:2) = maxval(box)
565 call mesh_double_box(space, der%mesh, fft_alpha, box)
567 box(:) = der%mesh%idx%ll(:)
568 end select
569
570 case (3)
571 select case (this%kernel)
573 call mesh_double_box(space, der%mesh, fft_alpha, box)
574 box(:) = maxval(box)
576 call mesh_double_box(space, der%mesh, fft_alpha, box)
577 box(2) = maxval(box(2:3)) ! max of finite directions
578 box(3) = maxval(box(2:3)) ! max of finite directions
580 box(:) = der%mesh%idx%ll(:)
582 call mesh_double_box(space, der%mesh, fft_alpha, box)
583 end select
584
585 end select
586
587 end if
588
589 ! Solvers that cannot transform a whole batch at once are applied one function at a time
590 ! (see X(poisson_solve_batch)) and do not need a batched cube.
591 if (.not. poisson_is_batch_capable(this)) fft_bs = 1
592
593 ! Create the cube
594 if (need_cube) then
595 call cube_init(this%cube, box, namespace, space, der%mesh%spacing, &
596 der%mesh%coord_system, fft_type = fft_type, &
597 need_partition=.not.der%mesh%parallel_in_domains, &
598 batch_size=fft_bs, single=single_precision)
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(this, namespace, pot, rho, all_nodes, kernel, reset)
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 logical, optional, intent(in) :: reset
677
678 logical :: all_nodes_value
679
680 push_sub(zpoisson_solve)
681
682 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
683
684 assert(ubound(pot, dim = 1) == this%der%mesh%np_part .or. ubound(pot, dim = 1) == this%der%mesh%np)
685 assert(ubound(rho, dim = 1) == this%der%mesh%np_part .or. ubound(rho, dim = 1) == this%der%mesh%np)
686
687 assert(this%method /= poisson_null)
688
689 if (poisson_solver_is_iterative(this) .and. optional_default(reset, .true.)) then
690 pot(1:this%der%mesh%np) = m_zero
691 end if
692
693 if (this%method == poisson_fft .and. this%kernel /= poisson_fft_kernel_corrected &
694 .and. .not. this%is_dressed) then
695 !The default (real) Poisson solver is used for OEP and Sternheimer calls were we do not need
696 !a complex-to-xomplex FFT as these parts use the normal Coulomb potential
697 if (this%cube%fft%type == fft_complex) then
698 !We add the profiling here, as the other path uses dpoisson_solve
699 call profiling_in('ZPOISSON_SOLVE')
700 call zpoisson_fft_solve(this%fft_solver, this%der%mesh, this%cube, pot, rho, this%mesh_cube_map, kernel=kernel)
701 call profiling_out('ZPOISSON_SOLVE')
702 else
703 call zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes_value, kernel=kernel)
704 end if
705 else
706 call zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes_value, kernel = kernel)
707 end if
708
709 pop_sub(zpoisson_solve)
710 end subroutine zpoisson_solve
711
712
713 !-----------------------------------------------------------------
714
715 subroutine poisson_solve_batch(this, namespace, potb, rhob, all_nodes, kernel)
716 type(poisson_t), intent(inout) :: this
717 type(namespace_t), intent(in) :: namespace
718 type(batch_t), intent(inout) :: potb
719 type(batch_t), intent(inout) :: rhob
720 logical, optional, intent(in) :: all_nodes
721 type(fourier_space_op_t), optional, intent(in) :: kernel
722
723 integer :: ii
724
725 push_sub(poisson_solve_batch)
726
727 assert(potb%nst_linear == rhob%nst_linear)
728 assert(potb%type() == rhob%type())
729
730 if (potb%type() == type_float) then
731 do ii = 1, potb%nst_linear
732 call dpoisson_solve(this, namespace, potb%dff_linear(:, ii), rhob%dff_linear(:, ii), all_nodes, kernel=kernel)
733 end do
734 else
735 do ii = 1, potb%nst_linear
736 call zpoisson_solve(this, namespace, potb%zff_linear(:, ii), rhob%zff_linear(:, ii), all_nodes, kernel=kernel)
737 end do
738 end if
739
740 pop_sub(poisson_solve_batch)
741 end subroutine poisson_solve_batch
742
743 !-----------------------------------------------------------------
749 logical function poisson_is_batch_capable(this)
750 type(poisson_t), intent(in) :: this
751
752 poisson_is_batch_capable = this%method == poisson_fft &
753 .and. this%kernel /= poisson_fft_kernel_corrected
754 end function poisson_is_batch_capable
755
756 !-----------------------------------------------------------------
758 logical function poisson_is_device_batch_capable(this)
759 type(poisson_t), intent(in) :: this
760
761 ! Tested in steps: only a batch-capable solver is guaranteed to have an FFT cube.
763 if (.not. accel_is_enabled()) return
764 if (.not. poisson_is_batch_capable(this)) return
765 poisson_is_device_batch_capable = this%cube%fft%library == fftlib_accel &
766 .and. .not. this%cube%parallel_in_domains
768
769 !-----------------------------------------------------------------
770
776 subroutine dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
777 type(poisson_t), intent(in) :: this
778 type(namespace_t), intent(in) :: namespace
779 real(real64), contiguous, intent(inout) :: pot(:)
780 real(real64), contiguous, intent(in) :: rho(:)
784 logical, optional, intent(in) :: all_nodes
785 type(fourier_space_op_t), optional, intent(in) :: kernel
786 logical, optional, intent(in) :: reset
787
788 type(derivatives_t), pointer :: der
789 real(real64), allocatable :: rho_corrected(:), vh_correction(:)
790 logical :: all_nodes_value
791
792 call profiling_in('POISSON_SOLVE')
793 push_sub(dpoisson_solve)
794
795 der => this%der
796
797 assert(ubound(pot, dim = 1) == der%mesh%np_part .or. ubound(pot, dim = 1) == der%mesh%np)
798 assert(ubound(rho, dim = 1) == der%mesh%np_part .or. ubound(rho, dim = 1) == der%mesh%np)
799
800 ! Check optional argument and set to default if necessary.
801 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
802
803 if (poisson_solver_is_iterative(this) .and. optional_default(reset, .true.)) then
804 pot(1:der%mesh%np) = m_zero
805 end if
806
807 assert(this%method /= poisson_null)
808
809 if (present(kernel)) then
810 assert(this%method == poisson_fft)
811 end if
812
813 select case (this%method)
814 case (poisson_direct_sum)
815 if ((this%is_dressed .and. this%der%dim - 1 > 3) .or. this%der%dim > 3) then
816 message(1) = "Direct sum Poisson solver only available for 1, 2, or 3 dimensions."
817 call messages_fatal(1, namespace=namespace)
818 end if
819 call poisson_solve_direct(this, namespace, pot, rho)
820
821 case (poisson_cg)
822 call poisson_cg1(namespace, der, this%corrector, pot, rho)
823
825 safe_allocate(rho_corrected(1:der%mesh%np))
826 safe_allocate(vh_correction(1:der%mesh%np_part))
827
828 call correct_rho(this%corrector, der, rho, rho_corrected, vh_correction)
830 call lalg_axpy(der%mesh%np, -m_one, vh_correction, pot)
831 call poisson_cg2(namespace, der, pot, rho_corrected)
832 call lalg_axpy(der%mesh%np, m_one, vh_correction, pot)
833
834 safe_deallocate_a(rho_corrected)
835 safe_deallocate_a(vh_correction)
836
837 case (poisson_multigrid)
838 call poisson_multigrid_solver(this%mg, namespace, der, pot, rho)
839
840 case (poisson_fft)
841 if (this%kernel /= poisson_fft_kernel_corrected) then
842 call dpoisson_fft_solve(this%fft_solver, der%mesh, this%cube, pot, rho, this%mesh_cube_map, kernel=kernel)
843 else
844 safe_allocate(rho_corrected(1:der%mesh%np))
845 safe_allocate(vh_correction(1:der%mesh%np_part))
846
847 call correct_rho(this%corrector, der, rho, rho_corrected, vh_correction)
848 call dpoisson_fft_solve(this%fft_solver, der%mesh, this%cube, pot, rho_corrected, this%mesh_cube_map, &
849 average_to_zero = .true., kernel=kernel)
850
851 call lalg_axpy(der%mesh%np, m_one, vh_correction, pot)
852 safe_deallocate_a(rho_corrected)
853 safe_deallocate_a(vh_correction)
854 end if
855
857 call poisson_isf_solve(this%isf_solver, der%mesh, this%cube, pot, rho, all_nodes_value)
858
859
860 case (poisson_psolver)
861 if (this%psolver_solver%datacode == "G") then
862 ! Global version
863 call poisson_psolver_global_solve(this%psolver_solver, der%mesh, this%cube, pot, rho)
864 else ! "D" Distributed version
865 call poisson_psolver_parallel_solve(this%psolver_solver, der%mesh, this%cube, pot, rho, this%mesh_cube_map)
866 end if
867
868 case (poisson_no)
869 call poisson_no_solve(this%no_solver, der%mesh, pot, rho)
870 end select
871
872 ! Add extra terms for dressed interaction
873 if (this%is_dressed .and. this%method /= poisson_no) then
874 call photon_mode_add_poisson_terms(this%photons, der%mesh, rho, pot)
875 end if
876
877 pop_sub(dpoisson_solve)
878 call profiling_out('POISSON_SOLVE')
879 end subroutine dpoisson_solve
880
881 !-----------------------------------------------------------------
882 subroutine poisson_init_sm(this, namespace, space, main, der, sm, grp, method, force_cmplx)
883 type(poisson_t), intent(inout) :: this
884 type(namespace_t), intent(in) :: namespace
885 class(space_t), intent(in) :: space
886 type(poisson_t), intent(in) :: main
887 type(derivatives_t), target, intent(in) :: der
888 type(submesh_t), intent(inout) :: sm
889 type(mpi_grp_t), intent(in) :: grp
890 integer, optional, intent(in) :: method
891 logical, optional, intent(in) :: force_cmplx
892
893 integer :: default_solver, idir, iter, maxl
894 integer :: box(space%dim)
895 real(real64) :: qq(der%dim), threshold
896
897 if (this%method /= poisson_null) return ! already initialized
898
899 push_sub(poisson_init_sm)
900
901 this%is_dressed = .false.
902 !TODO: To be implemented as an option
903 this%all_nodes_default = .false.
904
905 this%nslaves = 0
906 this%der => der
907
908#ifdef HAVE_MPI
909 this%all_nodes_default = main%all_nodes_default
910#endif
911
912 default_solver = poisson_direct_sum
913 this%method = default_solver
914 if (present(method)) this%method = method
915
916 if (der%mesh%use_curvilinear) then
917 call messages_not_implemented("Submesh Poisson solver with curvilinear mesh", namespace=namespace)
918 end if
919
920 this%kernel = poisson_fft_kernel_none
921
922 select case (this%method)
923 case (poisson_direct_sum)
924 !Nothing to be done
925
926 case (poisson_isf)
927 !TODO: Add support for domain parrallelization
928 assert(.not. der%mesh%parallel_in_domains)
929 call submesh_get_cube_dim(sm, space, box)
930 call submesh_init_cube_map(sm, space)
931 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
932 fft_type = fft_none, need_partition=.not.der%mesh%parallel_in_domains)
933 call cube_init_cube_map(this%cube, sm%mesh)
934 call poisson_isf_init(this%isf_solver, namespace, der%mesh, this%cube, grp%comm, init_world = this%all_nodes_default)
935
936 case (poisson_psolver)
937 !TODO: Add support for domain parrallelization
938 assert(.not. der%mesh%parallel_in_domains)
939 if (this%all_nodes_default) then
940 this%cube%mpi_grp = grp
941 else
942 this%cube%mpi_grp = this%der%mesh%mpi_grp
943 end if
944 call submesh_get_cube_dim(sm, space, box)
945 call submesh_init_cube_map(sm, space)
946 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
947 fft_type = fft_none, need_partition=.not.der%mesh%parallel_in_domains)
948 call cube_init_cube_map(this%cube, sm%mesh)
949 qq = m_zero
950 call poisson_psolver_init(this%psolver_solver, namespace, space, this%cube, m_zero, qq, force_isolated=.true.)
951 call poisson_psolver_get_dims(this%psolver_solver, this%cube)
952 case (poisson_fft)
953 !Here we impose zero boundary conditions
954 this%kernel = poisson_fft_kernel_sph
955
956 call submesh_get_cube_dim(sm, space, box)
957 call submesh_init_cube_map(sm, space)
958 !We double the size of the cell
959 !Maybe the factor of two should be controlled as a variable
960 do idir = 1, space%dim
961 box(idir) = (2 * (box(idir) - 1)) + 1
962 end do
963 if (optional_default(force_cmplx, .false.)) then
964 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
965 fft_type = fft_complex, need_partition=.not.der%mesh%parallel_in_domains)
966 else
967 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
968 fft_type = fft_real, need_partition=.not.der%mesh%parallel_in_domains)
969 end if
970 call poisson_fft_init(this%fft_solver, namespace, space, this%cube, this%kernel)
971 case (poisson_cg)
972 call parse_variable(namespace, 'PoissonSolverMaxMultipole', 4, maxl)
973 write(message(1),'(a,i2)')'Info: Boundary conditions fixed up to L =', maxl
974 call messages_info(1, namespace=namespace)
975 call parse_variable(namespace, 'PoissonSolverMaxIter', 500, iter)
976 call parse_variable(namespace, 'PoissonSolverThreshold', 1.0e-6_real64, threshold)
977 call poisson_corrections_init(this%corrector, namespace, space, maxl, this%der%mesh)
978 call poisson_cg_init(threshold, iter)
979 end select
980
981 pop_sub(poisson_init_sm)
982 end subroutine poisson_init_sm
983
984 ! -----------------------------------------------------------------
985
986 logical pure function poisson_solver_is_iterative(this) result(iterative)
987 type(poisson_t), intent(in) :: this
988
989 iterative = this%method == poisson_cg .or. this%method == poisson_cg_corrected
990 end function poisson_solver_is_iterative
991
992 !-----------------------------------------------------------------
993 subroutine poisson_async_init(this, mc)
994 type(poisson_t), intent(inout) :: this
995 type(multicomm_t), intent(in) :: mc
996
997 push_sub(poisson_async_init)
998
999#ifdef HAVE_MPI
1000 if (multicomm_have_slaves(mc)) then
1001
1002 call mpi_grp_init(this%local_grp, mc%group_comm(p_strategy_states))
1003
1004 this%root = (this%local_grp%is_root())
1005
1006 this%intercomm = mc%slave_intercomm
1007 call mpi_comm_remote_size(this%intercomm, this%nslaves)
1008
1009 end if
1010#endif
1011
1012 pop_sub(poisson_async_init)
1013
1014 end subroutine poisson_async_init
1015
1016 !-----------------------------------------------------------------
1017
1018 subroutine poisson_async_end(this, mc)
1019 type(poisson_t), intent(inout) :: this
1020 type(multicomm_t), intent(in) :: mc
1021
1022#ifdef HAVE_MPI
1023 integer :: islave
1024#endif
1025
1026 push_sub(poisson_async_end)
1027
1028#ifdef HAVE_MPI
1029 if (multicomm_have_slaves(mc)) then
1030
1031 ! send the finish signal
1032 do islave = this%local_grp%rank, this%nslaves - 1, this%local_grp%size
1033 call mpi_send(m_one, 1, mpi_double_precision, islave, cmd_finish, this%intercomm)
1034 end do
1035
1036 end if
1037#endif
1038
1039 pop_sub(poisson_async_end)
1040
1041 end subroutine poisson_async_end
1042
1043 !-----------------------------------------------------------------
1044
1045 subroutine poisson_slave_work(this, namespace)
1046 type(poisson_t), intent(inout) :: this
1047 type(namespace_t), intent(in) :: namespace
1048
1049#ifdef HAVE_MPI
1050 real(real64), allocatable :: rho(:), pot(:)
1051 logical :: done
1052 type(mpi_status) :: status
1053 integer :: bcast_root
1054
1055 push_sub(poisson_slave_work)
1056 call profiling_in("SLAVE_WORK")
1057
1058 safe_allocate(rho(1:this%der%mesh%np))
1059 safe_allocate(pot(1:this%der%mesh%np))
1060 done = .false.
1061
1062 do while(.not. done)
1063
1064 call profiling_in("SLAVE_WAIT")
1065 call mpi_recv(rho(1), this%der%mesh%np, mpi_double_precision, mpi_any_source, mpi_any_tag, this%intercomm, status)
1066 call profiling_out("SLAVE_WAIT")
1067
1068 ! The tag of the message tells us what we have to do.
1069 select case (status%MPI_TAG)
1070
1071 case (cmd_finish)
1072 done = .true.
1074 case (cmd_poisson_solve)
1075 call dpoisson_solve(this, namespace, pot, rho)
1076
1077 call profiling_in("SLAVE_BROADCAST")
1078 bcast_root = mpi_proc_null
1079 if (this%root) bcast_root = mpi_root
1080 call mpi_bcast(pot(1), this%der%mesh%np, mpi_double_precision, bcast_root, this%intercomm)
1081 call profiling_out("SLAVE_BROADCAST")
1082
1083 end select
1084
1085 end do
1086
1087 safe_deallocate_a(pot)
1088 safe_deallocate_a(rho)
1089
1090 call profiling_out("SLAVE_WORK")
1091 pop_sub(poisson_slave_work)
1092#endif
1093 end subroutine poisson_slave_work
1094
1095 !----------------------------------------------------------------
1096
1097 logical pure function poisson_is_async(this) result(async)
1098 type(poisson_t), intent(in) :: this
1099
1100 async = (this%nslaves > 0)
1102 end function poisson_is_async
1103
1104 !----------------------------------------------------------------
1105
1106 subroutine poisson_build_kernel(this, namespace, space, coulb, qq, cam, singul)
1107 type(poisson_t), intent(in) :: this
1108 type(namespace_t), intent(in) :: namespace
1109 class(space_t), intent(in) :: space
1110 type(fourier_space_op_t), intent(inout) :: coulb
1111 real(real64), intent(in) :: qq(:)
1112 type(xc_cam_t), intent(in) :: cam
1113 real(real64), optional, intent(in) :: singul
1114
1115 logical :: reinit
1116
1117 push_sub(poisson_build_kernel)
1119 if (space%is_periodic()) then
1120 assert(ubound(qq, 1) >= space%periodic_dim)
1121 assert(this%method == poisson_fft)
1122 end if
1123
1124 if (cam%omega > m_epsilon) then
1125 if (this%method /= poisson_fft) then
1126 write(message(1),'(a)') "Poisson solver with range separation is only implemented with FFT."
1127 call messages_fatal(1, namespace=namespace)
1128 end if
1129 end if
1130
1131 !We only reinitialize the poisson solver if needed
1132 reinit = .false.
1133 if (allocated(coulb%qq)) then
1134 reinit = any(abs(coulb%qq(1:space%periodic_dim) - qq(1:space%periodic_dim)) > m_epsilon)
1135 end if
1136 reinit = reinit .or. (abs(coulb%mu - cam%omega) > m_epsilon .and. cam%omega > m_epsilon)
1137 reinit = reinit .or. (abs(coulb%alpha - cam%alpha) > m_epsilon .and. cam%alpha > m_epsilon)
1138 reinit = reinit .or. (abs(coulb%beta - cam%beta) > m_epsilon .and. abs(cam%beta) > m_epsilon)
1139
1140 if (reinit) then
1141 call profiling_in('POISSON_BUILD_KERNEL')
1142 !TODO: this should be a select case supporting other kernels.
1143 ! This means that we need an abstract object for kernels.
1144 select case (this%method)
1145 case (poisson_fft)
1146 ! Check that we are consistent: the Poisson solver supports must return 1 here
1147 assert(is_close(poisson_get_full_range_weight(this, cam), m_one))
1148 call coulb%end()
1149 call coulb%init(space, qq, cam, singul)
1150 call poisson_fft_get_kernel(namespace, space, this%cube, coulb, this%kernel, &
1151 this%poisson_soft_coulomb_param)
1152 case default
1153 call messages_not_implemented("poisson_build_kernel with other methods than FFT", namespace=namespace)
1154 end select
1155 call profiling_out('POISSON_BUILD_KERNEL')
1156 end if
1157
1158 pop_sub(poisson_build_kernel)
1159 end subroutine poisson_build_kernel
1160
1161 !----------------------------------------------------------------
1170 real(real64) function poisson_get_full_range_weight(this, cam) result(weight)
1171 type(poisson_t), intent(in) :: this
1172 type(xc_cam_t), intent(in) :: cam
1173
1174 select case (this%method)
1175 case (poisson_fft)
1176 weight = m_one
1177 case default
1178 if(cam%omega < m_epsilon) then
1179 weight = cam%alpha
1180 else if(cam%alpha > m_epsilon .and. cam%beta < m_epsilon) then
1181 weight = cam%alpha
1182 else if(cam%alpha < m_epsilon .and. cam%beta > m_epsilon) then
1183 weight = cam%beta
1184 else
1185 assert(.false.)
1186 end if
1187 end select
1189
1190#include "poisson_init_inc.F90"
1191#include "poisson_direct_inc.F90"
1192#include "poisson_direct_sm_inc.F90"
1193
1194#include "undef.F90"
1195#include "real.F90"
1196#include "poisson_inc.F90"
1197#include "undef.F90"
1198#include "complex.F90"
1199#include "poisson_inc.F90"
1200#include "poisson_re_im_inc.F90"
1201
1202#include "undef.F90"
1203#include "real32.F90"
1204#include "poisson_inc.F90"
1205#include "undef.F90"
1206#include "complex32.F90"
1207#include "poisson_inc.F90"
1208#include "poisson_re_im_inc.F90"
1209
1210end module poisson_oct_m
1211
1212!! Local Variables:
1213!! mode: f90
1214!! coding: utf-8
1215!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:194
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:182
pure logical function, public accel_is_enabled()
Definition: accel.F90:414
This module implements batches of mesh functions.
Definition: batch.F90:135
This module handles the calculation mode.
integer, parameter, public p_strategy_kpoints
parallelization in k-points
subroutine, public cube_end(cube)
Definition: cube.F90:404
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, batch_size, nthreads, single)
Definition: cube.F90:208
subroutine, public cube_init_cube_map(cube, mesh)
Definition: cube.F90:887
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:120
integer, parameter, public fft_none
global constants
Definition: fft.F90:178
integer, public fft_default_lib
Definition: fft.F90:284
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:202
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_one
Definition: global.F90:201
real(real64), parameter, public m_three
Definition: global.F90:203
This module implements the index, used for the mesh points.
Definition: index.F90:124
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
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:120
subroutine, public mesh_double_box(space, mesh, alpha, db)
finds the dimension of a box doubled in the non-periodic dimensions
Definition: mesh.F90:286
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public 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:1040
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
logical pure function, public multicomm_strategy_is_parallel(mc, level)
Definition: multicomm.F90:728
logical pure function, public multicomm_have_slaves(this)
Definition: multicomm.F90:854
Some general things and nomenclature:
Definition: par_vec.F90:173
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:141
subroutine, public poisson_cg2(namespace, der, pot, rho)
Definition: poisson_cg.F90:231
subroutine, public poisson_cg1(namespace, der, corrector, pot, rho)
Definition: poisson_cg.F90:167
subroutine, public poisson_cg_init(thr, itr)
Definition: poisson_cg.F90:149
subroutine, public poisson_cg_end
Definition: poisson_cg.F90:161
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:164
subroutine, public poisson_no_end(this)
Definition: poisson_no.F90:152
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:2271
integer, parameter, public poisson_multigrid
Definition: poisson.F90:196
subroutine poisson_kernel_init(this, namespace, space, mc, stencil)
Definition: poisson.F90:1223
integer, parameter, public poisson_psolver
Definition: poisson.F90:196
subroutine, public dpoisson_solve_start(this, rho)
Definition: poisson.F90:1991
integer, parameter cmd_finish
Definition: poisson.F90:232
subroutine, public zpoisson_solve_finish(this, pot)
Definition: poisson.F90:2259
subroutine poisson_solve_direct(this, namespace, pot, rho)
Definition: poisson.F90:1434
integer, parameter, public poisson_fft
Definition: poisson.F90:196
subroutine, public spoisson_solve_batch(this, namespace, pot, rho, kernel, all_nodes, pot_buffer, rho_buffer, count)
Solves the Poisson equation for batched quantities, using fast Fourier transforms (FFTs).
Definition: poisson.F90:2822
subroutine, public spoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Single-precision scalar Poisson solve (FFT method only). This is the s/c counterpart of the concrete ...
Definition: poisson.F90:2775
subroutine, public zpoisson_solve_batch(this, namespace, pot, rho, kernel, all_nodes, pot_buffer, rho_buffer, count)
Solves the Poisson equation for batched quantities, using fast Fourier transforms (FFTs).
Definition: poisson.F90:2407
subroutine, public zpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Definition: poisson.F90:750
subroutine, public poisson_init_sm(this, namespace, space, main, der, sm, grp, method, force_cmplx)
Definition: poisson.F90:963
subroutine, public poisson_solve_batch(this, namespace, potb, rhob, all_nodes, kernel)
Definition: poisson.F90:796
subroutine, public poisson_async_init(this, mc)
Definition: poisson.F90:1074
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:2011
subroutine zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes, kernel)
Definition: poisson.F90:2518
subroutine, public cpoisson_solve_batch(this, namespace, pot, rho, kernel, all_nodes, pot_buffer, rho_buffer, count)
Solves the Poisson equation for batched quantities, using fast Fourier transforms (FFTs).
Definition: poisson.F90:3042
logical pure function poisson_solver_is_iterative(this)
Definition: poisson.F90:1067
subroutine, public poisson_slave_work(this, namespace)
Definition: poisson.F90:1102
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx, fft_batch_size, single_precision)
Definition: poisson.F90:241
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:857
integer, parameter cmd_poisson_solve
Definition: poisson.F90:232
integer, parameter, public poisson_cg
Definition: poisson.F90:196
subroutine, public poisson_build_kernel(this, namespace, space, coulb, qq, cam, singul)
Definition: poisson.F90:1119
subroutine, public dpoisson_solve_finish(this, pot)
Definition: poisson.F90:1999
subroutine, public zpoisson_solve_start(this, rho)
Definition: poisson.F90:2251
subroutine, public poisson_async_end(this, mc)
Definition: poisson.F90:1086
integer, parameter, public poisson_cg_corrected
Definition: poisson.F90:196
logical function, public poisson_is_device_batch_capable(this)
Whether a batch can be solved with the densities and potentials kept on the device.
Definition: poisson.F90:839
subroutine, public cpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Single-precision scalar Poisson solve (FFT method only). This is the s/c counterpart of the concrete ...
Definition: poisson.F90:2988
logical function, public poisson_is_batch_capable(this)
Whether this solver can transform a whole batch of functions in one call.
Definition: poisson.F90:830
integer, parameter, public poisson_isf
Definition: poisson.F90:196
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:1183
subroutine, public dpoisson_solve_batch(this, namespace, pot, rho, kernel, all_nodes, pot_buffer, rho_buffer, count)
Solves the Poisson equation for batched quantities, using fast Fourier transforms (FFTs).
Definition: poisson.F90:2091
integer, parameter, public poisson_null
Definition: poisson.F90:196
integer, parameter, public poisson_no
Definition: poisson.F90:196
logical pure function, public poisson_is_async(this)
Definition: poisson.F90:1110
subroutine, public poisson_end(this)
Definition: poisson.F90:697
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:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
This module defines stencils used in Octopus.
Definition: stencil.F90:137
subroutine, public submesh_init_cube_map(sm, space)
Definition: submesh.F90:935
subroutine, public submesh_get_cube_dim(sm, space, db)
finds the dimension of a box containing the submesh
Definition: submesh.F90:900
type(type_t), parameter, public type_float
Definition: types.F90:136
This module defines the unit system, used for input and output.
Class defining batches of mesh functions.
Definition: batch.F90:164
Class implementing a box that is a union of spheres. We do this in a specific class instead of using ...
class representing derivatives
Definition of a Fourier Space Coulomb Kernel.
This is defined even when running serial.
Definition: mpi.F90:144
A submesh is a type of mesh, used for the projectors in the pseudopotentials It contains points on a ...
Definition: submesh.F90:174
int true(void)