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_CUDA
263 if(accel_is_enabled()) default_solver = poisson_fft
264#endif
265
266 if (space%dim > 3) default_solver = poisson_no ! Kernel for higher dimensions is not implemented.
267
268 if (der%mesh%use_curvilinear) then
269 select case (space%dim)
270 case (1)
271 default_solver = poisson_direct_sum
272 case (2)
273 default_solver = poisson_direct_sum
274 case (3)
275 default_solver = poisson_multigrid
276 end select
277 end if
278
279 if (this%is_dressed) default_solver = poisson_direct_sum
280
281 if (.not. present(solver)) then
282 call parse_variable(namespace, 'PoissonSolver', default_solver, this%method)
283 else
284 this%method = solver
285 end if
286 if (.not. varinfo_valid_option('PoissonSolver', this%method)) call messages_input_error(namespace, 'PoissonSolver')
287 if (optional_default(verbose, .true.)) then
288 select case (this%method)
289 case (poisson_direct_sum)
290 str = "direct sum"
291 case (poisson_fft)
292 str = "fast Fourier transform"
293 case (poisson_cg)
294 str = "conjugate gradients"
296 str = "conjugate gradients, corrected"
297 case (poisson_multigrid)
298 str = "multigrid"
299 case (poisson_isf)
300 str = "interpolating scaling functions"
301 case (poisson_psolver)
302 str = "interpolating scaling functions (from BigDFT)"
303 case (poisson_no)
304 str = "no Poisson solver - Hartree set to 0"
305 end select
306 write(message(1),'(a,a,a)') "The chosen Poisson solver is '", trim(str), "'"
307 call messages_info(1, namespace=namespace)
308 end if
309
310 if (space%dim > 3 .and. this%method /= poisson_no) then
311 call messages_input_error(namespace, 'PoissonSolver', 'Currently no Poisson solver is available for Dimensions > 3')
312 end if
313
314 if (this%method /= poisson_fft) then
315 this%kernel = poisson_fft_kernel_none
316 else
317
318 ! Documentation in cube.F90
319 call parse_variable(namespace, 'FFTLibrary', fftlib_fftw, fft_library)
320
321 !%Variable PoissonFFTKernel
322 !%Type integer
323 !%Section Hamiltonian::Poisson
324 !%Description
325 !% Defines which kernel is used to impose the correct boundary
326 !% conditions when using FFTs to solve the Poisson equation. The
327 !% default is selected depending on the dimensionality and
328 !% periodicity of the system:
329 !% <br>In 1D, <tt>spherical</tt> if finite, <tt>fft_nocut</tt> if periodic.
330 !% <br>In 2D, <tt>spherical</tt> if finite, <tt>cylindrical</tt> if 1D-periodic, <tt>fft_nocut</tt> if 2D-periodic.
331 !% <br>In 3D, <tt>spherical</tt> if finite, <tt>cylindrical</tt> if 1D-periodic, <tt>planar</tt> if 2D-periodic,
332 !% <tt>fft_nocut</tt> if 3D-periodic.
333 !% See C. A. Rozzi et al., <i>Phys. Rev. B</i> <b>73</b>, 205119 (2006) for 3D implementation and
334 !% A. Castro et al., <i>Phys. Rev. B</i> <b>80</b>, 033102 (2009) for 2D implementation.
335 !%Option spherical 0
336 !% FFTs using spherical cutoff (in 2D or 3D).
337 !%Option cylindrical 1
338 !% FFTs using cylindrical cutoff (in 2D or 3D).
339 !%Option planar 2
340 !% FFTs using planar cutoff (in 3D).
341 !%Option fft_nocut 3
342 !% FFTs without using a cutoff (for fully periodic systems).
343 !%Option multipole_correction 4
344 !% The boundary conditions are imposed by using a multipole expansion. Only appropriate for finite systems.
345 !% Further specification occurs with variables <tt>PoissonSolverBoundaries</tt> and <tt>PoissonSolverMaxMultipole</tt>.
346 !%End
347
348 select case (space%dim)
349 case (1)
350 if (.not. space%is_periodic()) then
351 default_kernel = poisson_fft_kernel_sph
352 else
353 default_kernel = poisson_fft_kernel_nocut
354 end if
355 case (2)
356 if (space%periodic_dim == 2) then
357 default_kernel = poisson_fft_kernel_nocut
358 else if (space%is_periodic()) then
359 default_kernel = space%periodic_dim
360 else
361 default_kernel = poisson_fft_kernel_sph
362 end if
363 case (3)
364 default_kernel = space%periodic_dim
365 end select
366
367 call parse_variable(namespace, 'PoissonFFTKernel', default_kernel, this%kernel)
368 if (.not. varinfo_valid_option('PoissonFFTKernel', this%kernel)) call messages_input_error(namespace, 'PoissonFFTKernel')
369
370 if (optional_default(verbose,.true.)) then
371 call messages_print_var_option("PoissonFFTKernel", this%kernel, namespace=namespace)
372 end if
373
374 ! the multipole correction kernel does not work on GPUs
375 if(this%kernel == poisson_fft_kernel_corrected .and. fft_default_lib == fftlib_accel) then
377 message(1) = 'PoissonFFTKernel=multipole_correction is not supported on GPUs'
378 message(2) = 'Using FFTW to compute the FFTs on the CPU'
379 call messages_info(2, namespace=namespace)
380 end if
381
382 end if
383
384 !We assume the developer knows what he is doing by providing the solver option
385 if (.not. present(solver)) then
386 if (space%is_periodic() .and. this%method == poisson_direct_sum) then
387 message(1) = 'A periodic system may not use the direct_sum Poisson solver.'
388 call messages_fatal(1, namespace=namespace)
389 end if
390
391 if (space%is_periodic() .and. this%method == poisson_cg_corrected) then
392 message(1) = 'A periodic system may not use the cg_corrected Poisson solver.'
393 call messages_fatal(1, namespace=namespace)
394 end if
395
396 if (space%is_periodic() .and. this%method == poisson_cg) then
397 message(1) = 'A periodic system may not use the cg Poisson solver.'
398 call messages_fatal(1, namespace=namespace)
399 end if
400
401 if (space%is_periodic() .and. this%method == poisson_multigrid) then
402 message(1) = 'A periodic system may not use the multigrid 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 solver 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 dimentions
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 ! Create the cube
590 if (need_cube) then
591 call cube_init(this%cube, box, namespace, space, der%mesh%spacing, &
592 der%mesh%coord_system, fft_type = fft_type, &
593 need_partition=.not.der%mesh%parallel_in_domains)
594 call cube_init_cube_map(this%cube, der%mesh)
595 if (this%cube%parallel_in_domains .and. this%method == poisson_fft) then
596 call mesh_cube_parallel_map_init(this%mesh_cube_map, der%mesh, this%cube)
597 end if
598 end if
599
600 if (this%is_dressed .and. .not. this%method == poisson_direct_sum) then
601 write(message(1), '(a)')'Dressed Orbital calculation currently only working with direct sum Poisson solver.'
602 call messages_fatal(1, namespace=namespace)
603 end if
604
605 call poisson_kernel_init(this, namespace, space, mc, stencil)
606
607 pop_sub(poisson_init)
608 end subroutine poisson_init
609
610 !-----------------------------------------------------------------
611 subroutine poisson_end(this)
612 type(poisson_t), intent(inout) :: this
613
614 logical :: has_cube
615
616 push_sub(poisson_end)
617
618 has_cube = .false.
619
620 select case (this%method)
621 case (poisson_fft)
622 call poisson_fft_end(this%fft_solver)
623 if (this%kernel == poisson_fft_kernel_corrected) call poisson_corrections_end(this%corrector)
624 has_cube = .true.
625
627 call poisson_cg_end()
628 call poisson_corrections_end(this%corrector)
629
630 case (poisson_multigrid)
631 call poisson_multigrid_end(this%mg)
632
633 case (poisson_isf)
634 call poisson_isf_end(this%isf_solver)
635 has_cube = .true.
636
637 case (poisson_psolver)
638 call poisson_psolver_end(this%psolver_solver)
639 has_cube = .true.
640
641 case (poisson_no)
642 call poisson_no_end(this%no_solver)
643
644 end select
645 this%method = poisson_null
646
647 if (has_cube) then
648 if (this%cube%parallel_in_domains) then
649 call mesh_cube_parallel_map_end(this%mesh_cube_map)
650 end if
651 call cube_end(this%cube)
652 end if
653
654 if (this%is_dressed) then
655 call photon_mode_end(this%photons)
656 end if
657 this%is_dressed = .false.
658
659 pop_sub(poisson_end)
660 end subroutine poisson_end
661
662 !-----------------------------------------------------------------
663
664 subroutine zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes, kernel)
665 type(poisson_t), intent(in) :: this
666 type(namespace_t), intent(in) :: namespace
667 complex(real64), contiguous, intent(inout) :: pot(:)
668 complex(real64), contiguous, intent(in) :: rho(:)
669 logical, optional, intent(in) :: all_nodes
670 type(fourier_space_op_t), optional, intent(in) :: kernel
671
672 real(real64), allocatable :: aux1(:), aux2(:)
673 type(derivatives_t), pointer :: der
674 logical :: all_nodes_value
675
676
677 der => this%der
678
680
681 call profiling_in('POISSON_RE_IM_SOLVE')
682
683 if (present(kernel)) then
684 assert(.not. any(abs(kernel%qq(:))>1e-8_real64))
685 end if
686
687 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
688
689 safe_allocate(aux1(1:der%mesh%np))
690 safe_allocate(aux2(1:der%mesh%np))
691 ! first the real part
692 aux1(1:der%mesh%np) = real(rho(1:der%mesh%np), real64)
693 aux2(1:der%mesh%np) = real(pot(1:der%mesh%np), real64)
694 call dpoisson_solve(this, namespace, aux2, aux1, all_nodes=all_nodes_value, kernel=kernel)
695 pot(1:der%mesh%np) = aux2(1:der%mesh%np)
696
697 ! now the imaginary part
698 aux1(1:der%mesh%np) = aimag(rho(1:der%mesh%np))
699 aux2(1:der%mesh%np) = aimag(pot(1:der%mesh%np))
700 call dpoisson_solve(this, namespace, aux2, aux1, all_nodes=all_nodes_value, kernel=kernel)
701 pot(1:der%mesh%np) = pot(1:der%mesh%np) + m_zi*aux2(1:der%mesh%np)
702
703 safe_deallocate_a(aux1)
704 safe_deallocate_a(aux2)
705
706 call profiling_out('POISSON_RE_IM_SOLVE')
707
710
711 !-----------------------------------------------------------------
712
713 subroutine zpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
714 type(poisson_t), intent(in) :: this
715 type(namespace_t), intent(in) :: namespace
716 complex(real64), contiguous, intent(inout) :: pot(:)
717 complex(real64), contiguous, intent(in) :: rho(:)
718 logical, optional, intent(in) :: all_nodes
719 type(fourier_space_op_t), optional, intent(in) :: kernel
720 logical, optional, intent(in) :: reset
721
722 logical :: all_nodes_value
723
724 push_sub(zpoisson_solve)
725
726 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
727
728 assert(ubound(pot, dim = 1) == this%der%mesh%np_part .or. ubound(pot, dim = 1) == this%der%mesh%np)
729 assert(ubound(rho, dim = 1) == this%der%mesh%np_part .or. ubound(rho, dim = 1) == this%der%mesh%np)
730
731 assert(this%method /= poisson_null)
732
733 if (poisson_solver_is_iterative(this) .and. optional_default(reset, .true.)) then
734 pot(1:this%der%mesh%np) = m_zero
735 end if
736
737 if (this%method == poisson_fft .and. this%kernel /= poisson_fft_kernel_corrected &
738 .and. .not. this%is_dressed) then
739 !The default (real) Poisson solver is used for OEP and Sternheimer calls were we do not need
740 !a complex-to-xomplex FFT as these parts use the normal Coulomb potential
741 if (this%cube%fft%type == fft_complex) then
742 !We add the profiling here, as the other path uses dpoisson_solve
743 call profiling_in('ZPOISSON_SOLVE')
744 call zpoisson_fft_solve(this%fft_solver, this%der%mesh, this%cube, pot, rho, this%mesh_cube_map, kernel=kernel)
745 call profiling_out('ZPOISSON_SOLVE')
746 else
747 call zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes_value, kernel=kernel)
748 end if
749 else
750 call zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes_value, kernel = kernel)
751 end if
752
753 pop_sub(zpoisson_solve)
754 end subroutine zpoisson_solve
755
756
757 !-----------------------------------------------------------------
758
759 subroutine poisson_solve_batch(this, namespace, potb, rhob, all_nodes, kernel)
760 type(poisson_t), intent(inout) :: this
761 type(namespace_t), intent(in) :: namespace
762 type(batch_t), intent(inout) :: potb
763 type(batch_t), intent(inout) :: rhob
764 logical, optional, intent(in) :: all_nodes
765 type(fourier_space_op_t), optional, intent(in) :: kernel
766
767 integer :: ii
768
769 push_sub(poisson_solve_batch)
770
771 assert(potb%nst_linear == rhob%nst_linear)
772 assert(potb%type() == rhob%type())
773
774 if (potb%type() == type_float) then
775 do ii = 1, potb%nst_linear
776 call dpoisson_solve(this, namespace, potb%dff_linear(:, ii), rhob%dff_linear(:, ii), all_nodes, kernel=kernel)
777 end do
778 else
779 do ii = 1, potb%nst_linear
780 call zpoisson_solve(this, namespace, potb%zff_linear(:, ii), rhob%zff_linear(:, ii), all_nodes, kernel=kernel)
781 end do
782 end if
783
784 pop_sub(poisson_solve_batch)
785 end subroutine poisson_solve_batch
786
787 !-----------------------------------------------------------------
788
794 subroutine dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
795 type(poisson_t), intent(in) :: this
796 type(namespace_t), intent(in) :: namespace
797 real(real64), contiguous, intent(inout) :: pot(:)
798 real(real64), contiguous, intent(in) :: rho(:)
802 logical, optional, intent(in) :: all_nodes
803 type(fourier_space_op_t), optional, intent(in) :: kernel
804 logical, optional, intent(in) :: reset
805
806 type(derivatives_t), pointer :: der
807 real(real64), allocatable :: rho_corrected(:), vh_correction(:)
808 logical :: all_nodes_value
809
810 call profiling_in('POISSON_SOLVE')
811 push_sub(dpoisson_solve)
812
813 der => this%der
814
815 assert(ubound(pot, dim = 1) == der%mesh%np_part .or. ubound(pot, dim = 1) == der%mesh%np)
816 assert(ubound(rho, dim = 1) == der%mesh%np_part .or. ubound(rho, dim = 1) == der%mesh%np)
817
818 ! Check optional argument and set to default if necessary.
819 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
820
821 if (poisson_solver_is_iterative(this) .and. optional_default(reset, .true.)) then
822 pot(1:der%mesh%np) = m_zero
823 end if
824
825 assert(this%method /= poisson_null)
826
827 if (present(kernel)) then
828 assert(this%method == poisson_fft)
829 end if
830
831 select case (this%method)
832 case (poisson_direct_sum)
833 if ((this%is_dressed .and. this%der%dim - 1 > 3) .or. this%der%dim > 3) then
834 message(1) = "Direct sum Poisson solver only available for 1, 2, or 3 dimensions."
835 call messages_fatal(1, namespace=namespace)
836 end if
837 call poisson_solve_direct(this, namespace, pot, rho)
838
840 call poisson_cg1(namespace, der, this%corrector, pot, rho)
841
843 safe_allocate(rho_corrected(1:der%mesh%np))
844 safe_allocate(vh_correction(1:der%mesh%np_part))
845
846 call correct_rho(this%corrector, der, rho, rho_corrected, vh_correction)
847
848 pot(1:der%mesh%np) = pot(1:der%mesh%np) - vh_correction(1:der%mesh%np)
849 call poisson_cg2(namespace, der, pot, rho_corrected)
850 pot(1:der%mesh%np) = pot(1:der%mesh%np) + vh_correction(1:der%mesh%np)
851
852 safe_deallocate_a(rho_corrected)
853 safe_deallocate_a(vh_correction)
854
855 case (poisson_multigrid)
856 call poisson_multigrid_solver(this%mg, namespace, der, pot, rho)
857
858 case (poisson_fft)
859 if (this%kernel /= poisson_fft_kernel_corrected) then
860 call dpoisson_fft_solve(this%fft_solver, der%mesh, this%cube, pot, rho, this%mesh_cube_map, kernel=kernel)
861 else
862 safe_allocate(rho_corrected(1:der%mesh%np))
863 safe_allocate(vh_correction(1:der%mesh%np_part))
864
865 call correct_rho(this%corrector, der, rho, rho_corrected, vh_correction)
866 call dpoisson_fft_solve(this%fft_solver, der%mesh, this%cube, pot, rho_corrected, this%mesh_cube_map, &
867 average_to_zero = .true., kernel=kernel)
868
869 pot(1:der%mesh%np) = pot(1:der%mesh%np) + vh_correction(1:der%mesh%np)
870 safe_deallocate_a(rho_corrected)
871 safe_deallocate_a(vh_correction)
872 end if
873
875 call poisson_isf_solve(this%isf_solver, der%mesh, this%cube, pot, rho, all_nodes_value)
876
877
878 case (poisson_psolver)
879 if (this%psolver_solver%datacode == "G") then
880 ! Global version
881 call poisson_psolver_global_solve(this%psolver_solver, der%mesh, this%cube, pot, rho)
882 else ! "D" Distributed version
883 call poisson_psolver_parallel_solve(this%psolver_solver, der%mesh, this%cube, pot, rho, this%mesh_cube_map)
884 end if
885
886 case (poisson_no)
887 call poisson_no_solve(this%no_solver, der%mesh, pot, rho)
888 end select
889
890
891 ! Add extra terms for dressed interaction
892 if (this%is_dressed .and. this%method /= poisson_no) then
893 call photon_mode_add_poisson_terms(this%photons, der%mesh, rho, pot)
894 end if
895
896 pop_sub(dpoisson_solve)
897 call profiling_out('POISSON_SOLVE')
898 end subroutine dpoisson_solve
899
900 !-----------------------------------------------------------------
901 subroutine poisson_init_sm(this, namespace, space, main, der, sm, method, force_cmplx)
902 type(poisson_t), intent(inout) :: this
903 type(namespace_t), intent(in) :: namespace
904 class(space_t), intent(in) :: space
905 type(poisson_t), intent(in) :: main
906 type(derivatives_t), target, intent(in) :: der
907 type(submesh_t), intent(inout) :: sm
908 integer, optional, intent(in) :: method
909 logical, optional, intent(in) :: force_cmplx
910
911 integer :: default_solver, idir, iter, maxl
912 integer :: box(space%dim)
913 real(real64) :: qq(der%dim), threshold
914
915 if (this%method /= poisson_null) return ! already initialized
916
917 push_sub(poisson_init_sm)
918
919 this%is_dressed = .false.
920 !TODO: To be implemented as an option
921 this%all_nodes_default = .false.
922
923 this%nslaves = 0
924 this%der => der
925
926#ifdef HAVE_MPI
927 this%all_nodes_default = main%all_nodes_default
928#endif
929
930 default_solver = poisson_direct_sum
931 this%method = default_solver
932 if (present(method)) this%method = method
933
934 if (der%mesh%use_curvilinear) then
935 call messages_not_implemented("Submesh Poisson solver with curvilinear mesh", namespace=namespace)
936 end if
937
938 this%kernel = poisson_fft_kernel_none
939
940 select case (this%method)
941 case (poisson_direct_sum)
942 !Nothing to be done
943
944 case (poisson_isf)
945 !TODO: Add support for domain parrallelization
946 assert(.not. der%mesh%parallel_in_domains)
947 call submesh_get_cube_dim(sm, space, box)
948 call submesh_init_cube_map(sm, space)
949 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
950 fft_type = fft_none, need_partition=.not.der%mesh%parallel_in_domains)
951 call cube_init_cube_map(this%cube, sm%mesh)
952 call poisson_isf_init(this%isf_solver, namespace, der%mesh, this%cube, mpi_world%comm, init_world = this%all_nodes_default)
953
954 case (poisson_psolver)
955 !TODO: Add support for domain parrallelization
956 assert(.not. der%mesh%parallel_in_domains)
957 if (this%all_nodes_default) then
958 this%cube%mpi_grp = mpi_world
959 else
960 this%cube%mpi_grp = this%der%mesh%mpi_grp
961 end if
962 call submesh_get_cube_dim(sm, space, box)
963 call submesh_init_cube_map(sm, space)
964 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
965 fft_type = fft_none, need_partition=.not.der%mesh%parallel_in_domains)
966 call cube_init_cube_map(this%cube, sm%mesh)
967 qq = m_zero
968 call poisson_psolver_init(this%psolver_solver, namespace, space, this%cube, m_zero, qq, force_isolated=.true.)
969 call poisson_psolver_get_dims(this%psolver_solver, this%cube)
970 case (poisson_fft)
971 !Here we impose zero boundary conditions
972 this%kernel = poisson_fft_kernel_sph
973 !We need to parse this, in case this routine is called before poisson_init
974 call parse_variable(namespace, 'FFTLibrary', fftlib_fftw, fft_default_lib)
975
976 call submesh_get_cube_dim(sm, space, box)
977 call submesh_init_cube_map(sm, space)
978 !We double the size of the cell
979 !Maybe the factor of two should be controlled as a variable
980 do idir = 1, space%dim
981 box(idir) = (2 * (box(idir) - 1)) + 1
982 end do
983 if (optional_default(force_cmplx, .false.)) then
984 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
985 fft_type = fft_complex, need_partition=.not.der%mesh%parallel_in_domains)
986 else
987 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
988 fft_type = fft_real, need_partition=.not.der%mesh%parallel_in_domains)
989 end if
990 call poisson_fft_init(this%fft_solver, namespace, space, this%cube, this%kernel)
991 case (poisson_cg)
992 call parse_variable(namespace, 'PoissonSolverMaxMultipole', 4, maxl)
993 write(message(1),'(a,i2)')'Info: Boundary conditions fixed up to L =', maxl
994 call messages_info(1, namespace=namespace)
995 call parse_variable(namespace, 'PoissonSolverMaxIter', 500, iter)
996 call parse_variable(namespace, 'PoissonSolverThreshold', 1.0e-6_real64, threshold)
997 call poisson_corrections_init(this%corrector, namespace, space, maxl, this%der%mesh)
998 call poisson_cg_init(threshold, iter)
999 end select
1000
1001 pop_sub(poisson_init_sm)
1002 end subroutine poisson_init_sm
1003
1004 ! -----------------------------------------------------------------
1005
1006 logical pure function poisson_solver_is_iterative(this) result(iterative)
1007 type(poisson_t), intent(in) :: this
1008
1009 iterative = this%method == poisson_cg .or. this%method == poisson_cg_corrected
1010 end function poisson_solver_is_iterative
1011
1012 ! -----------------------------------------------------------------
1013
1014 logical pure function poisson_is_multigrid(this) result(is_multigrid)
1015 type(poisson_t), intent(in) :: this
1016
1017 is_multigrid = (this%method == poisson_multigrid)
1018
1019 end function poisson_is_multigrid
1020
1021 ! -----------------------------------------------------------------
1022
1023 logical pure function poisson_solver_has_free_bc(this) result(free_bc)
1024 type(poisson_t), intent(in) :: this
1025
1026 free_bc = .true.
1027
1028 if (this%method == poisson_fft .and. &
1029 this%kernel /= poisson_fft_kernel_sph .and. this%kernel /= poisson_fft_kernel_corrected) then
1030 free_bc = .false.
1031 end if
1032
1033 end function poisson_solver_has_free_bc
1034
1035 !-----------------------------------------------------------------
1036
1037 integer pure function poisson_get_solver(this) result (solver)
1038 type(poisson_t), intent(in) :: this
1039
1040 solver = this%method
1041 end function poisson_get_solver
1042
1043 !-----------------------------------------------------------------
1044
1045 subroutine poisson_async_init(this, mc)
1046 type(poisson_t), intent(inout) :: this
1047 type(multicomm_t), intent(in) :: mc
1048
1049 push_sub(poisson_async_init)
1050
1051#ifdef HAVE_MPI
1052 if (multicomm_have_slaves(mc)) then
1053
1054 call mpi_grp_init(this%local_grp, mc%group_comm(p_strategy_states))
1055
1056 this%root = (this%local_grp%is_root())
1057
1058 this%intercomm = mc%slave_intercomm
1059 call mpi_comm_remote_size(this%intercomm, this%nslaves)
1060
1061 end if
1062#endif
1063
1064 pop_sub(poisson_async_init)
1065
1066 end subroutine poisson_async_init
1067
1068 !-----------------------------------------------------------------
1069
1070 subroutine poisson_async_end(this, mc)
1071 type(poisson_t), intent(inout) :: this
1072 type(multicomm_t), intent(in) :: mc
1073
1074#ifdef HAVE_MPI
1075 integer :: islave
1076#endif
1077
1078 push_sub(poisson_async_end)
1079
1080#ifdef HAVE_MPI
1081 if (multicomm_have_slaves(mc)) then
1082
1083 ! send the finish signal
1084 do islave = this%local_grp%rank, this%nslaves - 1, this%local_grp%size
1085 call mpi_send(m_one, 1, mpi_double_precision, islave, cmd_finish, this%intercomm)
1086 end do
1087
1088 end if
1089#endif
1090
1091 pop_sub(poisson_async_end)
1092
1093 end subroutine poisson_async_end
1095 !-----------------------------------------------------------------
1096
1097 subroutine poisson_slave_work(this, namespace)
1098 type(poisson_t), intent(inout) :: this
1099 type(namespace_t), intent(in) :: namespace
1100
1101#ifdef HAVE_MPI
1102 real(real64), allocatable :: rho(:), pot(:)
1103 logical :: done
1104 type(mpi_status) :: status
1105 integer :: bcast_root
1106
1107 push_sub(poisson_slave_work)
1108 call profiling_in("SLAVE_WORK")
1109
1110 safe_allocate(rho(1:this%der%mesh%np))
1111 safe_allocate(pot(1:this%der%mesh%np))
1112 done = .false.
1113
1114 do while(.not. done)
1115
1116 call profiling_in("SLAVE_WAIT")
1117 call mpi_recv(rho(1), this%der%mesh%np, mpi_double_precision, mpi_any_source, mpi_any_tag, this%intercomm, status)
1118 call profiling_out("SLAVE_WAIT")
1119
1120 ! The tag of the message tells us what we have to do.
1121 select case (status%MPI_TAG)
1122
1123 case (cmd_finish)
1124 done = .true.
1126 case (cmd_poisson_solve)
1127 call dpoisson_solve(this, namespace, pot, rho)
1128
1129 call profiling_in("SLAVE_BROADCAST")
1130 bcast_root = mpi_proc_null
1131 if (this%root) bcast_root = mpi_root
1132 call mpi_bcast(pot(1), this%der%mesh%np, mpi_double_precision, bcast_root, this%intercomm)
1133 call profiling_out("SLAVE_BROADCAST")
1134
1135 end select
1136
1137 end do
1138
1139 safe_deallocate_a(pot)
1140 safe_deallocate_a(rho)
1141
1142 call profiling_out("SLAVE_WORK")
1143 pop_sub(poisson_slave_work)
1144#endif
1145 end subroutine poisson_slave_work
1146
1147 !----------------------------------------------------------------
1148
1149 logical pure function poisson_is_async(this) result(async)
1150 type(poisson_t), intent(in) :: this
1151
1152 async = (this%nslaves > 0)
1154 end function poisson_is_async
1155
1156 !----------------------------------------------------------------
1157
1158 subroutine poisson_build_kernel(this, namespace, space, coulb, qq, cam, singul)
1159 type(poisson_t), intent(in) :: this
1160 type(namespace_t), intent(in) :: namespace
1161 class(space_t), intent(in) :: space
1162 type(fourier_space_op_t), intent(inout) :: coulb
1163 real(real64), intent(in) :: qq(:)
1164 type(xc_cam_t), intent(in) :: cam
1165 real(real64), optional, intent(in) :: singul
1166
1167 real(real64), parameter :: vanishing_q = 1.0e-5_real64
1168 logical :: reinit
1169
1171
1172 if (space%is_periodic()) then
1173 assert(ubound(qq, 1) >= space%periodic_dim)
1174 assert(this%method == poisson_fft)
1175 end if
1176
1177 if (cam%omega > m_epsilon) then
1178 if (this%method /= poisson_fft) then
1179 write(message(1),'(a)') "Poisson solver with range separation is only implemented with FFT."
1180 call messages_fatal(1, namespace=namespace)
1181 end if
1182 end if
1183
1184 !We only reinitialize the poisson solver if needed
1185 reinit = .false.
1186 if (allocated(coulb%qq)) then
1187 reinit = any(abs(coulb%qq(1:space%periodic_dim) - qq(1:space%periodic_dim)) > m_epsilon)
1188 end if
1189 reinit = reinit .or. (abs(coulb%mu - cam%omega) > m_epsilon .and. cam%omega > m_epsilon)
1190 reinit = reinit .or. (abs(coulb%alpha - cam%alpha) > m_epsilon .and. cam%alpha > m_epsilon)
1191 reinit = reinit .or. (abs(coulb%beta - cam%beta) > m_epsilon .and. cam%beta > m_epsilon)
1192
1193 if (reinit) then
1194 !TODO: this should be a select case supporting other kernels.
1195 ! This means that we need an abstract object for kernels.
1196 select case (this%method)
1197 case (poisson_fft)
1198 ! Check that we are consistent: the Poisson solver supports must return 1 here
1199 assert(is_close(poisson_get_full_range_weight(this, cam), m_one))
1200
1201 call fourier_space_op_end(coulb)
1202
1203 safe_allocate(coulb%qq(1:space%dim))
1204 coulb%qq(1:space%periodic_dim) = qq(1:space%periodic_dim)
1205 coulb%qq(space%periodic_dim+1:space%dim) = vanishing_q
1206 !We must define the singularity if we specify a q vector and we do not use the short-range Coulomb potential
1207 coulb%singularity = optional_default(singul, m_zero)
1208 coulb%mu = cam%omega
1209 coulb%alpha = cam%alpha
1210 coulb%beta = cam%beta
1211 call poisson_fft_get_kernel(namespace, space, this%cube, coulb, this%kernel, &
1212 this%poisson_soft_coulomb_param)
1213 case default
1214 call messages_not_implemented("poisson_build_kernel with other methods than FFT", namespace=namespace)
1215 end select
1216 end if
1217
1218 pop_sub(poisson_build_kernel)
1219 end subroutine poisson_build_kernel
1220
1221 !----------------------------------------------------------------
1230 real(real64) function poisson_get_full_range_weight(this, cam) result(weight)
1231 type(poisson_t), intent(in) :: this
1232 type(xc_cam_t), intent(in) :: cam
1233
1234 select case (this%method)
1235 case (poisson_fft)
1236 weight = m_one
1237 case default
1238 if(cam%omega < m_epsilon) then
1239 weight = cam%alpha
1240 else if(cam%alpha > m_epsilon .and. cam%beta < m_epsilon) then
1241 weight = cam%alpha
1242 else if(cam%alpha < m_epsilon .and. cam%beta > m_epsilon) then
1243 weight = cam%beta
1244 else
1245 assert(.false.)
1246 end if
1247 end select
1249
1250#include "poisson_init_inc.F90"
1251#include "poisson_direct_inc.F90"
1252#include "poisson_direct_sm_inc.F90"
1253
1254#include "undef.F90"
1255#include "real.F90"
1256#include "poisson_inc.F90"
1257#include "undef.F90"
1258#include "complex.F90"
1259#include "poisson_inc.F90"
1260
1261end module poisson_oct_m
1262
1263!! Local Variables:
1264!! mode: f90
1265!! coding: utf-8
1266!! End:
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:380
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_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:204
subroutine, public cube_end(cube)
Definition: cube.F90:387
subroutine, public cube_init_cube_map(cube, mesh)
Definition: cube.F90:824
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:174
integer, public fft_default_lib
Definition: fft.F90:250
integer, parameter, public fftlib_accel
Definition: fft.F90:179
integer, parameter, public fft_real
Definition: fft.F90:174
integer, parameter, public fft_complex
Definition: fft.F90:174
integer, parameter, public fftlib_pfft
Definition: fft.F90:179
integer, parameter, public fftlib_fftw
Definition: fft.F90:179
real(real64), parameter, public m_two
Definition: global.F90:193
real(real64), parameter, public m_zero
Definition: global.F90:191
complex(real64), parameter, public m_zi
Definition: global.F90:205
real(real64), parameter, public m_one
Definition: global.F90:192
real(real64), parameter, public m_three
Definition: global.F90:194
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:284
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1091
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:1063
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:272
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
logical pure function, public multicomm_strategy_is_parallel(mc, level)
Definition: multicomm.F90:719
logical pure function, public multicomm_have_slaves(this)
Definition: multicomm.F90:845
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:140
subroutine, public poisson_cg2(namespace, der, pot, rho)
Definition: poisson_cg.F90:217
subroutine, public poisson_cg1(namespace, der, corrector, pot, rho)
Definition: poisson_cg.F90:166
subroutine, public poisson_cg_init(thr, itr)
Definition: poisson_cg.F90:148
subroutine, public poisson_cg_end
Definition: poisson_cg.F90:160
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:165
subroutine, public poisson_no_end(this)
Definition: poisson_no.F90:153
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:2208
integer, parameter, public poisson_multigrid
Definition: poisson.F90:192
subroutine poisson_kernel_init(this, namespace, space, mc, stencil)
Definition: poisson.F90:1283
integer, parameter, public poisson_psolver
Definition: poisson.F90:192
subroutine, public dpoisson_solve_start(this, rho)
Definition: poisson.F90:2029
integer, parameter cmd_finish
Definition: poisson.F90:228
subroutine, public zpoisson_solve_finish(this, pot)
Definition: poisson.F90:2196
subroutine poisson_solve_direct(this, namespace, pot, rho)
Definition: poisson.F90:1487
integer, parameter, public poisson_fft
Definition: poisson.F90:192
logical pure function, public poisson_is_multigrid(this)
Definition: poisson.F90:1095
subroutine, public zpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Definition: poisson.F90:794
subroutine, public poisson_solve_batch(this, namespace, potb, rhob, all_nodes, kernel)
Definition: poisson.F90:840
subroutine, public poisson_async_init(this, mc)
Definition: poisson.F90:1126
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:2049
subroutine zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes, kernel)
Definition: poisson.F90:745
subroutine, public poisson_init_sm(this, namespace, space, main, der, sm, method, force_cmplx)
Definition: poisson.F90:982
logical pure function poisson_solver_is_iterative(this)
Definition: poisson.F90:1087
subroutine, public poisson_slave_work(this, namespace)
Definition: poisson.F90:1154
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:875
integer, parameter cmd_poisson_solve
Definition: poisson.F90:228
integer, parameter, public poisson_cg
Definition: poisson.F90:192
subroutine, public poisson_build_kernel(this, namespace, space, coulb, qq, cam, singul)
Definition: poisson.F90:1171
logical pure function, public poisson_solver_has_free_bc(this)
Definition: poisson.F90:1104
subroutine, public dpoisson_solve_finish(this, pot)
Definition: poisson.F90:2037
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx)
Definition: poisson.F90:236
subroutine, public zpoisson_solve_start(this, rho)
Definition: poisson.F90:2188
subroutine, public poisson_async_end(this, mc)
Definition: poisson.F90:1138
integer, parameter, public poisson_cg_corrected
Definition: poisson.F90:192
integer pure function, public poisson_get_solver(this)
Definition: poisson.F90:1118
integer, parameter, public poisson_isf
Definition: poisson.F90:192
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:1243
integer, parameter, public poisson_null
Definition: poisson.F90:192
integer, parameter, public poisson_no
Definition: poisson.F90:192
logical pure function, public poisson_is_async(this)
Definition: poisson.F90:1162
subroutine, public poisson_end(this)
Definition: poisson.F90:692
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:1009
subroutine, public submesh_get_cube_dim(sm, space, db)
finds the dimension of a box containing the submesh
Definition: submesh.F90:974
type(type_t), public type_float
Definition: types.F90:135
This module defines the unit system, used for input and output.
Class defining batches of mesh functions.
Definition: batch.F90:161
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:177
int true(void)