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