Octopus
poisson.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2011 M. Marques, A. Castro, A. Rubio,
2!! G. Bertsch, M. Oliveira
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
22module poisson_oct_m
23 use accel_oct_m
24 use batch_oct_m
27 use cube_oct_m
29 use debug_oct_m
31 use fft_oct_m
33 use global_oct_m
34 use index_oct_m
35 use, intrinsic :: iso_fortran_env
38 use math_oct_m
39 use mesh_oct_m
43 use mpi_oct_m
46#ifdef HAVE_OPENMP
47 use omp_lib
48#endif
50 use parser_oct_m
61 use space_oct_m
64 use types_oct_m
67 use xc_cam_oct_m
68
69 implicit none
70
71 private
72 public :: &
73 poisson_t, &
92
93 integer, public, parameter :: &
94 POISSON_DIRECT_SUM = -1, &
95 poisson_fft = 0, &
96 poisson_cg = 5, &
99 poisson_isf = 8, &
100 poisson_psolver = 10, &
101 poisson_no = -99, &
102 poisson_null = -999
103
104 type poisson_t
105 private
106 type(derivatives_t), pointer, public :: der
107 integer, public :: method = poisson_null
108 integer, public :: kernel
109 type(cube_t), public :: cube
110 type(mesh_cube_parallel_map_t), public :: mesh_cube_map
111 type(poisson_mg_solver_t) :: mg
112 type(poisson_fft_t), public :: fft_solver
113 real(real64), public :: poisson_soft_coulomb_param
114 logical :: all_nodes_default
115 type(poisson_corr_t) :: corrector
116 type(poisson_isf_t) :: isf_solver
117 type(poisson_psolver_t) :: psolver_solver
118 type(poisson_no_t) :: no_solver
119 integer :: nslaves
120 logical, public :: is_dressed = .false.
121 type(photon_mode_t), public :: photons
122#ifdef HAVE_MPI
123 type(MPI_Comm) :: intercomm
124 type(mpi_grp_t) :: local_grp
125 logical :: root
126#endif
127 end type poisson_t
128
129 integer, parameter :: &
130 CMD_FINISH = 1, &
132
133contains
134
135 !-----------------------------------------------------------------
136 subroutine poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx)
137 type(poisson_t), intent(inout) :: this
138 class(space_t), intent(in) :: space
139 type(namespace_t), intent(in) :: namespace
140 type(derivatives_t), target, intent(in) :: der
141 type(multicomm_t), intent(in) :: mc
142 type(stencil_t), intent(in) :: stencil
143 real(real64), optional, intent(in) :: qtot
144 character(len=*), optional, intent(in) :: label
145 integer, optional, intent(in) :: solver
146 logical, optional, intent(in) :: verbose
147 logical, optional, intent(in) :: force_serial
148 logical, optional, intent(in) :: force_cmplx
149
150 logical :: need_cube, isf_data_is_parallel
151 integer :: default_solver, default_kernel, box(space%dim), fft_type, fft_library
152 real(real64) :: fft_alpha
153 character(len=60) :: str
154
155 ! Make sure we do not try to initialize an already initialized solver
156 assert(this%method == poisson_null)
157
158 push_sub(poisson_init)
159
160 if (optional_default(verbose,.true.)) then
161 str = "Hartree"
162 if (present(label)) str = trim(label)
163 call messages_print_with_emphasis(msg=trim(str), namespace=namespace)
164 end if
165
166 this%nslaves = 0
167 this%der => der
168
169 !%Variable DressedOrbitals
170 !%Type logical
171 !%Default false
172 !%Section Hamiltonian::Poisson
173 !%Description
174 !% Allows for the calculation of coupled elecron-photon problems
175 !% by applying the dressed orbital approach. Details can be found in
176 !% https://arxiv.org/abs/1812.05562
177 !% At the moment, N electrons in d (<=3) spatial dimensions, coupled
178 !% to one photon mode can be described. The photon mode is included by
179 !% raising the orbital dimension to d+1 and changing the particle interaction
180 !% kernel and the local potential, where the former is included automatically,
181 !% but the latter needs to by added by hand as a user_defined_potential!
182 !% Coordinate 1-d: electron; coordinate d+1: photon.
183 !%End
184 call parse_variable(namespace, 'DressedOrbitals', .false., this%is_dressed)
185 call messages_print_var_value('DressedOrbitals', this%is_dressed, namespace=namespace)
186 if (this%is_dressed) then
187 assert(present(qtot))
188 call messages_experimental('Dressed Orbitals', namespace=namespace)
189 assert(qtot > m_zero)
190 call photon_mode_init(this%photons, namespace, der%dim-1)
191 call photon_mode_set_n_electrons(this%photons, qtot)
192 if(.not.allocated(this%photons%pol_dipole)) then
193 call photon_mode_compute_dipoles(this%photons, der%mesh)
194 end if
195 if (this%photons%nmodes > 1) then
196 call messages_not_implemented('DressedOrbitals for more than one photon mode', namespace=namespace)
197 end if
198 end if
200 this%all_nodes_default = .false.
201#ifdef HAVE_MPI
202 if (.not. optional_default(force_serial, .false.)) then
203 !%Variable ParallelizationPoissonAllNodes
204 !%Type logical
205 !%Default true
206 !%Section Execution::Parallelization
207 !%Description
208 !% When running in parallel, this variable selects whether the
209 !% Poisson solver should divide the work among all nodes or only
210 !% among the parallelization-in-domains groups.
211 !%End
213 call parse_variable(namespace, 'ParallelizationPoissonAllNodes', .true., this%all_nodes_default)
214 end if
215#endif
217 !%Variable PoissonSolver
218 !%Type integer
219 !%Section Hamiltonian::Poisson
220 !%Description
221 !% Defines which method to use to solve the Poisson equation. Some incompatibilities apply depending on
222 !% dimensionality, periodicity, etc.
223 !% For a comparison of the accuracy and performance of the methods in Octopus, see P Garcia-Risue&ntilde;o,
224 !% J Alberdi-Rodriguez <i>et al.</i>, <i>J. Comp. Chem.</i> <b>35</b>, 427-444 (2014)
225 !% or <a href=http://arxiv.org/abs/1211.2092>arXiV</a>.
226 !% Defaults:
227 !% <br> 1D and 2D: <tt>fft</tt>.
228 !% <br> 3D: <tt>cg_corrected</tt> if curvilinear, <tt>isf</tt> if not periodic, <tt>fft</tt> if periodic.
229 !% <br> Dressed orbitals: <tt>direct_sum</tt>.
230 !%Option NoPoisson -99
231 !% Do not use a Poisson solver at all.
232 !%Option direct_sum -1
233 !% Direct evaluation of the Hartree potential (only for finite systems).
234 !%Option fft 0
235 !% The Poisson equation is solved using FFTs. A cutoff technique
236 !% for the Poisson kernel is selected so the proper boundary
237 !% conditions are imposed according to the periodicity of the
238 !% system. This can be overridden by the <tt>PoissonFFTKernel</tt>
239 !% variable. To choose the FFT library use <tt>FFTLibrary</tt>
240 !%Option cg 5
241 !% Conjugate gradients.
242 !%Option cg_corrected 6
243 !% Conjugate gradients, corrected for boundary conditions (only for finite systems).
244 !%Option multigrid 7
245 !% Multigrid method.
246 !%Option isf 8
247 !% Interpolating Scaling Functions Poisson solver (only for finite systems).
248 !%Option psolver 10
249 !% Solver based on Interpolating Scaling Functions as implemented in the PSolver library.
250 !% Parallelization in k-points requires <tt>PoissonSolverPSolverParallelData</tt> = no.
251 !% Requires the PSolver external library.
252 !%End
253
254 default_solver = poisson_fft
255
256 if (space%dim == 3 .and. .not. space%is_periodic()) default_solver = poisson_isf
257
258#ifdef HAVE_CUDA
259 if(accel_is_enabled()) default_solver = poisson_fft
260#endif
261
262 if (space%dim > 3) default_solver = poisson_no ! Kernel for higher dimensions is not implemented.
263
264 if (der%mesh%use_curvilinear) then
265 select case (space%dim)
266 case (1)
267 default_solver = poisson_direct_sum
268 case (2)
269 default_solver = poisson_direct_sum
270 case (3)
271 default_solver = poisson_multigrid
272 end select
273 end if
274
275 if (this%is_dressed) default_solver = poisson_direct_sum
276
277 if (.not. present(solver)) then
278 call parse_variable(namespace, 'PoissonSolver', default_solver, this%method)
279 else
280 this%method = solver
281 end if
282 if (.not. varinfo_valid_option('PoissonSolver', this%method)) call messages_input_error(namespace, 'PoissonSolver')
283 if (optional_default(verbose, .true.)) then
284 select case (this%method)
285 case (poisson_direct_sum)
286 str = "direct sum"
287 case (poisson_fft)
288 str = "fast Fourier transform"
289 case (poisson_cg)
290 str = "conjugate gradients"
292 str = "conjugate gradients, corrected"
293 case (poisson_multigrid)
294 str = "multigrid"
295 case (poisson_isf)
296 str = "interpolating scaling functions"
297 case (poisson_psolver)
298 str = "interpolating scaling functions (from BigDFT)"
299 case (poisson_no)
300 str = "no Poisson solver - Hartree set to 0"
301 end select
302 write(message(1),'(a,a,a)') "The chosen Poisson solver is '", trim(str), "'"
303 call messages_info(1, namespace=namespace)
304 end if
305
306 if (space%dim > 3 .and. this%method /= poisson_no) then
307 call messages_input_error(namespace, 'PoissonSolver', 'Currently no Poisson solver is available for Dimensions > 3')
308 end if
309
310 if (this%method /= poisson_fft) then
311 this%kernel = poisson_fft_kernel_none
312 else
313
314 ! Documentation in cube.F90
315 call parse_variable(namespace, 'FFTLibrary', fftlib_fftw, fft_library)
316
317 !%Variable PoissonFFTKernel
318 !%Type integer
319 !%Section Hamiltonian::Poisson
320 !%Description
321 !% Defines which kernel is used to impose the correct boundary
322 !% conditions when using FFTs to solve the Poisson equation. The
323 !% default is selected depending on the dimensionality and
324 !% periodicity of the system:
325 !% <br>In 1D, <tt>spherical</tt> if finite, <tt>fft_nocut</tt> if periodic.
326 !% <br>In 2D, <tt>spherical</tt> if finite, <tt>cylindrical</tt> if 1D-periodic, <tt>fft_nocut</tt> if 2D-periodic.
327 !% <br>In 3D, <tt>spherical</tt> if finite, <tt>cylindrical</tt> if 1D-periodic, <tt>planar</tt> if 2D-periodic,
328 !% <tt>fft_nocut</tt> if 3D-periodic.
329 !% See C. A. Rozzi et al., <i>Phys. Rev. B</i> <b>73</b>, 205119 (2006) for 3D implementation and
330 !% A. Castro et al., <i>Phys. Rev. B</i> <b>80</b>, 033102 (2009) for 2D implementation.
331 !%Option spherical 0
332 !% FFTs using spherical cutoff (in 2D or 3D).
333 !%Option cylindrical 1
334 !% FFTs using cylindrical cutoff (in 2D or 3D).
335 !%Option planar 2
336 !% FFTs using planar cutoff (in 3D).
337 !%Option fft_nocut 3
338 !% FFTs without using a cutoff (for fully periodic systems).
339 !%Option multipole_correction 4
340 !% The boundary conditions are imposed by using a multipole expansion. Only appropriate for finite systems.
341 !% Further specification occurs with variables <tt>PoissonSolverBoundaries</tt> and <tt>PoissonSolverMaxMultipole</tt>.
342 !%End
343
344 select case (space%dim)
345 case (1)
346 if (.not. space%is_periodic()) then
347 default_kernel = poisson_fft_kernel_sph
348 else
349 default_kernel = poisson_fft_kernel_nocut
350 end if
351 case (2)
352 if (space%periodic_dim == 2) then
353 default_kernel = poisson_fft_kernel_nocut
354 else if (space%is_periodic()) then
355 default_kernel = space%periodic_dim
356 else
357 default_kernel = poisson_fft_kernel_sph
358 end if
359 case (3)
360 default_kernel = space%periodic_dim
361 end select
362
363 call parse_variable(namespace, 'PoissonFFTKernel', default_kernel, this%kernel)
364 if (.not. varinfo_valid_option('PoissonFFTKernel', this%kernel)) call messages_input_error(namespace, 'PoissonFFTKernel')
365
366 if (optional_default(verbose,.true.)) then
367 call messages_print_var_option("PoissonFFTKernel", this%kernel, namespace=namespace)
368 end if
369
370 ! the multipole correction kernel does not work on GPUs
371 if(this%kernel == poisson_fft_kernel_corrected .and. fft_default_lib == fftlib_accel) then
373 message(1) = 'PoissonFFTKernel=multipole_correction is not supported on GPUs'
374 message(2) = 'Using FFTW to compute the FFTs on the CPU'
375 call messages_info(2, namespace=namespace)
376 end if
377
378 end if
379
380 !We assume the developer knows what he is doing by providing the solver option
381 if (.not. present(solver)) then
382 if (space%is_periodic() .and. this%method == poisson_direct_sum) then
383 message(1) = 'A periodic system may not use the direct_sum Poisson solver.'
384 call messages_fatal(1, namespace=namespace)
385 end if
386
387 if (space%is_periodic() .and. this%method == poisson_cg_corrected) then
388 message(1) = 'A periodic system may not use the cg_corrected Poisson solver.'
389 call messages_fatal(1, namespace=namespace)
390 end if
391
392
393 select case (space%dim)
394 case (1)
395
396 select case (space%periodic_dim)
397 case (0)
398 if ((this%method /= poisson_fft) .and. (this%method /= poisson_direct_sum)) then
399 message(1) = 'A finite 1D system may only use fft or direct_sum Poisson solvers.'
400 call messages_fatal(1, namespace=namespace)
401 end if
402 case (1)
403 if (this%method /= poisson_fft) then
404 message(1) = 'A periodic 1D system may only use the fft Poisson solver.'
405 call messages_fatal(1, namespace=namespace)
406 end if
407 end select
408
409 if (der%mesh%use_curvilinear .and. this%method /= poisson_direct_sum) then
410 message(1) = 'If curvilinear coordinates are used in 1D, then the only working'
411 message(2) = 'Poisson solver is direct_sum.'
412 call messages_fatal(2, namespace=namespace)
413 end if
414
415 case (2)
416
417 if ((this%method /= poisson_fft) .and. (this%method /= poisson_direct_sum)) then
418 message(1) = 'A 2D system may only use fft or direct_sum solvers.'
419 call messages_fatal(1, namespace=namespace)
420 end if
421
422 if (der%mesh%use_curvilinear .and. (this%method /= poisson_direct_sum)) then
423 message(1) = 'If curvilinear coordinates are used in 2D, 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 (3)
429
430 if (space%is_periodic() .and. this%method == poisson_isf) then
431 call messages_write('The ISF solver can only be used for finite systems.')
432 call messages_fatal()
433 end if
434
435 if (space%is_periodic() .and. this%method == poisson_fft .and. &
436 this%kernel /= space%periodic_dim .and. this%kernel >= 0 .and. this%kernel <= 3) then
437 write(message(1), '(a,i1,a)')'The system is periodic in ', space%periodic_dim ,' dimension(s),'
438 write(message(2), '(a,i1,a)')'but Poisson solver is set for ', this%kernel, ' dimensions.'
439 call messages_warning(2, namespace=namespace)
440 end if
441
442 if (space%is_periodic() .and. this%method == poisson_fft .and. this%kernel == poisson_fft_kernel_corrected) then
443 write(message(1), '(a,i1,a)')'PoissonFFTKernel = multipole_correction cannot be used for periodic systems.'
444 call messages_fatal(1, namespace=namespace)
445 end if
446
447 if (der%mesh%use_curvilinear .and. .not. any(this%method == [poisson_cg_corrected, poisson_multigrid])) then
448 message(1) = 'If curvilinear coordinates are used, then the only working'
449 message(2) = 'Poisson solvers are cg_corrected and multigrid.'
450 call messages_fatal(2, namespace=namespace)
451 end if
452 if (der%mesh%use_curvilinear .and. this%method == poisson_multigrid .and. accel_is_enabled()) then
453 call messages_not_implemented('Multigrid Poisson solver with curvilinear coordinates on GPUs')
454 end if
455
456 select type (box => der%mesh%box)
457 type is (box_minimum_t)
458 if (this%method == poisson_cg_corrected) then
459 message(1) = 'When using the "minimum" box shape and the "cg_corrected"'
460 message(2) = 'Poisson solver, we have observed "sometimes" some non-'
461 message(3) = 'negligible error. You may want to check that the "fft" or "cg"'
462 message(4) = 'solver are providing, in your case, the same results.'
463 call messages_warning(4, namespace=namespace)
464 end if
465 end select
466
467 end select
468 end if
469
470 if (this%method == poisson_psolver) then
471#if !(defined HAVE_PSOLVER)
472 message(1) = "The PSolver Poisson solver cannot be used since the code was not compiled with the PSolver library."
473 call messages_fatal(1, namespace=namespace)
474#endif
475 end if
476
477 if (optional_default(verbose,.true.)) then
478 call messages_print_with_emphasis(namespace=namespace)
479 end if
480
481 ! Now that we know the method, we check if we need a cube and its dimentions
482 need_cube = .false.
483 fft_type = fft_real
484 if (optional_default(force_cmplx, .false.)) fft_type = fft_complex
485
486 if (this%method == poisson_isf .or. this%method == poisson_psolver) then
487 fft_type = fft_none
488 box(:) = der%mesh%idx%ll(:)
489 need_cube = .true.
490 end if
491
492 if (this%method == poisson_psolver .and. multicomm_have_slaves(mc)) then
493 call messages_not_implemented('Task parallelization with PSolver Poisson solver', namespace=namespace)
494 end if
495
497 ! Documentation in poisson_psolver.F90
498 call parse_variable(namespace, 'PoissonSolverPSolverParallelData', .true., isf_data_is_parallel)
499 if (this%method == poisson_psolver .and. isf_data_is_parallel) then
500 call messages_not_implemented("k-point parallelization with PSolver library and", namespace=namespace)
501 call messages_not_implemented("PoissonSolverPSolverParallelData = yes", namespace=namespace)
502 end if
503 if (this%method == poisson_fft .and. fft_library == fftlib_pfft) then
504 call messages_not_implemented("k-point parallelization with PFFT library for", namespace=namespace)
505 call messages_not_implemented("PFFT library for Poisson solver", namespace=namespace)
506 end if
507 end if
508
509 if (this%method == poisson_fft) then
510
511 need_cube = .true.
512
513 !%Variable DoubleFFTParameter
514 !%Type float
515 !%Default 2.0
516 !%Section Mesh::FFTs
517 !%Description
518 !% For solving the Poisson equation in Fourier space, and for applying the local potential
519 !% in Fourier space, an auxiliary cubic mesh is built. This mesh will be larger than
520 !% the circumscribed cube of the usual mesh by a factor <tt>DoubleFFTParameter</tt>. See
521 !% the section that refers to Poisson equation, and to the local potential for details
522 !% [the default value of two is typically good].
523 !%End
524 call parse_variable(namespace, 'DoubleFFTParameter', m_two, fft_alpha)
525 if (fft_alpha < m_one .or. fft_alpha > m_three) then
526 write(message(1), '(a,f12.5,a)') "Input: '", fft_alpha, &
527 "' is not a valid DoubleFFTParameter"
528 message(2) = '1.0 <= DoubleFFTParameter <= 3.0'
529 call messages_fatal(2, namespace=namespace)
530 end if
531
532 if (space%dim /= 3 .and. fft_library == fftlib_pfft) then
533 call messages_not_implemented('PFFT support for dimensionality other than 3', namespace=namespace)
534 end if
535
536 select case (space%dim)
537
538 case (1)
539 select case (this%kernel)
541 call mesh_double_box(space, der%mesh, fft_alpha, box)
543 box = der%mesh%idx%ll
544 end select
545
546 case (2)
547 select case (this%kernel)
549 call mesh_double_box(space, der%mesh, fft_alpha, box)
550 box(1:2) = maxval(box)
552 call mesh_double_box(space, der%mesh, fft_alpha, box)
554 box(:) = der%mesh%idx%ll(:)
555 end select
556
557 case (3)
558 select case (this%kernel)
560 call mesh_double_box(space, der%mesh, fft_alpha, box)
561 box(:) = maxval(box)
563 call mesh_double_box(space, der%mesh, fft_alpha, box)
564 box(2) = maxval(box(2:3)) ! max of finite directions
565 box(3) = maxval(box(2:3)) ! max of finite directions
567 box(:) = der%mesh%idx%ll(:)
569 call mesh_double_box(space, der%mesh, fft_alpha, box)
570 end select
571
572 end select
573
574 end if
575
576 ! Create the cube
577 if (need_cube) then
578 call cube_init(this%cube, box, namespace, space, der%mesh%spacing, &
579 der%mesh%coord_system, fft_type = fft_type, &
580 need_partition=.not.der%mesh%parallel_in_domains)
581 call cube_init_cube_map(this%cube, der%mesh)
582 if (this%cube%parallel_in_domains .and. this%method == poisson_fft) then
583 call mesh_cube_parallel_map_init(this%mesh_cube_map, der%mesh, this%cube)
584 end if
585 end if
586
587 if (this%is_dressed .and. .not. this%method == poisson_direct_sum) then
588 write(message(1), '(a)')'Dressed Orbital calculation currently only working with direct sum Poisson solver.'
589 call messages_fatal(1, namespace=namespace)
590 end if
591
592 call poisson_kernel_init(this, namespace, space, mc, stencil)
593
594 pop_sub(poisson_init)
595 end subroutine poisson_init
596
597 !-----------------------------------------------------------------
598 subroutine poisson_end(this)
599 type(poisson_t), intent(inout) :: this
600
601 logical :: has_cube
602
603 push_sub(poisson_end)
604
605 has_cube = .false.
606
607 select case (this%method)
608 case (poisson_fft)
609 call poisson_fft_end(this%fft_solver)
610 if (this%kernel == poisson_fft_kernel_corrected) call poisson_corrections_end(this%corrector)
611 has_cube = .true.
612
614 call poisson_cg_end()
615 call poisson_corrections_end(this%corrector)
616
617 case (poisson_multigrid)
618 call poisson_multigrid_end(this%mg)
619
620 case (poisson_isf)
621 call poisson_isf_end(this%isf_solver)
622 has_cube = .true.
623
624 case (poisson_psolver)
625 call poisson_psolver_end(this%psolver_solver)
626 has_cube = .true.
627
628 case (poisson_no)
629 call poisson_no_end(this%no_solver)
630
631 end select
632 this%method = poisson_null
633
634 if (has_cube) then
635 if (this%cube%parallel_in_domains) then
636 call mesh_cube_parallel_map_end(this%mesh_cube_map)
637 end if
638 call cube_end(this%cube)
639 end if
640
641 if (this%is_dressed) then
642 call photon_mode_end(this%photons)
643 end if
644 this%is_dressed = .false.
645
646 pop_sub(poisson_end)
647 end subroutine poisson_end
648
649 !-----------------------------------------------------------------
650
651 subroutine zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes, kernel)
652 type(poisson_t), intent(in) :: this
653 type(namespace_t), intent(in) :: namespace
654 complex(real64), contiguous, intent(inout) :: pot(:)
655 complex(real64), contiguous, intent(in) :: rho(:)
656 logical, optional, intent(in) :: all_nodes
657 type(fourier_space_op_t), optional, intent(in) :: kernel
658
659 real(real64), allocatable :: aux1(:), aux2(:)
660 type(derivatives_t), pointer :: der
661 logical :: all_nodes_value
662
663
664 der => this%der
665
667
668 call profiling_in('POISSON_RE_IM_SOLVE')
669
670 if (present(kernel)) then
671 assert(.not. any(abs(kernel%qq(:))>1e-8_real64))
672 end if
673
674 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
675
676 safe_allocate(aux1(1:der%mesh%np))
677 safe_allocate(aux2(1:der%mesh%np))
678 ! first the real part
679 aux1(1:der%mesh%np) = real(rho(1:der%mesh%np), real64)
680 aux2(1:der%mesh%np) = real(pot(1:der%mesh%np), real64)
681 call dpoisson_solve(this, namespace, aux2, aux1, all_nodes=all_nodes_value, kernel=kernel)
682 pot(1:der%mesh%np) = aux2(1:der%mesh%np)
683
684 ! now the imaginary part
685 aux1(1:der%mesh%np) = aimag(rho(1:der%mesh%np))
686 aux2(1:der%mesh%np) = aimag(pot(1:der%mesh%np))
687 call dpoisson_solve(this, namespace, aux2, aux1, all_nodes=all_nodes_value, kernel=kernel)
688 pot(1:der%mesh%np) = pot(1:der%mesh%np) + m_zi*aux2(1:der%mesh%np)
689
690 safe_deallocate_a(aux1)
691 safe_deallocate_a(aux2)
692
693 call profiling_out('POISSON_RE_IM_SOLVE')
694
697
698 !-----------------------------------------------------------------
699
700 subroutine zpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
701 type(poisson_t), intent(in) :: this
702 type(namespace_t), intent(in) :: namespace
703 complex(real64), contiguous, intent(inout) :: pot(:)
704 complex(real64), contiguous, intent(in) :: rho(:)
705 logical, optional, intent(in) :: all_nodes
706 type(fourier_space_op_t), optional, intent(in) :: kernel
707 logical, optional, intent(in) :: reset
708
709 logical :: all_nodes_value
710
711 push_sub(zpoisson_solve)
712
713 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
714
715 assert(ubound(pot, dim = 1) == this%der%mesh%np_part .or. ubound(pot, dim = 1) == this%der%mesh%np)
716 assert(ubound(rho, dim = 1) == this%der%mesh%np_part .or. ubound(rho, dim = 1) == this%der%mesh%np)
717
718 assert(this%method /= poisson_null)
719
720 if (poisson_solver_is_iterative(this) .and. optional_default(reset, .true.)) then
721 pot(1:this%der%mesh%np) = m_zero
722 end if
723
724 if (this%method == poisson_fft .and. this%kernel /= poisson_fft_kernel_corrected &
725 .and. .not. this%is_dressed) then
726 !The default (real) Poisson solver is used for OEP and Sternheimer calls were we do not need
727 !a complex-to-xomplex FFT as these parts use the normal Coulomb potential
728 if (this%cube%fft%type == fft_complex) then
729 !We add the profiling here, as the other path uses dpoisson_solve
730 call profiling_in('ZPOISSON_SOLVE')
731 call zpoisson_fft_solve(this%fft_solver, this%der%mesh, this%cube, pot, rho, this%mesh_cube_map, kernel=kernel)
732 call profiling_out('ZPOISSON_SOLVE')
733 else
734 call zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes_value, kernel=kernel)
735 end if
736 else
737 call zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes_value, kernel = kernel)
738 end if
739
740 pop_sub(zpoisson_solve)
741 end subroutine zpoisson_solve
742
743
744 !-----------------------------------------------------------------
745
746 subroutine poisson_solve_batch(this, namespace, potb, rhob, all_nodes, kernel)
747 type(poisson_t), intent(inout) :: this
748 type(namespace_t), intent(in) :: namespace
749 type(batch_t), intent(inout) :: potb
750 type(batch_t), intent(inout) :: rhob
751 logical, optional, intent(in) :: all_nodes
752 type(fourier_space_op_t), optional, intent(in) :: kernel
753
754 integer :: ii
755
756 push_sub(poisson_solve_batch)
757
758 assert(potb%nst_linear == rhob%nst_linear)
759 assert(potb%type() == rhob%type())
760
761 if (potb%type() == type_float) then
762 do ii = 1, potb%nst_linear
763 call dpoisson_solve(this, namespace, potb%dff_linear(:, ii), rhob%dff_linear(:, ii), all_nodes, kernel=kernel)
764 end do
765 else
766 do ii = 1, potb%nst_linear
767 call zpoisson_solve(this, namespace, potb%zff_linear(:, ii), rhob%zff_linear(:, ii), all_nodes, kernel=kernel)
768 end do
769 end if
770
771 pop_sub(poisson_solve_batch)
772 end subroutine poisson_solve_batch
773
774 !-----------------------------------------------------------------
775
781 subroutine dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
782 type(poisson_t), intent(in) :: this
783 type(namespace_t), intent(in) :: namespace
784 real(real64), contiguous, intent(inout) :: pot(:)
785 real(real64), contiguous, intent(in) :: rho(:)
789 logical, optional, intent(in) :: all_nodes
790 type(fourier_space_op_t), optional, intent(in) :: kernel
791 logical, optional, intent(in) :: reset
792
793 type(derivatives_t), pointer :: der
794 real(real64), allocatable :: rho_corrected(:), vh_correction(:)
795 logical :: all_nodes_value
796
797 call profiling_in('POISSON_SOLVE')
798 push_sub(dpoisson_solve)
799
800 der => this%der
801
802 assert(ubound(pot, dim = 1) == der%mesh%np_part .or. ubound(pot, dim = 1) == der%mesh%np)
803 assert(ubound(rho, dim = 1) == der%mesh%np_part .or. ubound(rho, dim = 1) == der%mesh%np)
804
805 ! Check optional argument and set to default if necessary.
806 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
807
808 if (poisson_solver_is_iterative(this) .and. optional_default(reset, .true.)) then
809 pot(1:der%mesh%np) = m_zero
810 end if
811
812 assert(this%method /= poisson_null)
813
814 if (present(kernel)) then
815 assert(this%method == poisson_fft)
816 end if
817
818 select case (this%method)
819 case (poisson_direct_sum)
820 if ((this%is_dressed .and. this%der%dim - 1 > 3) .or. this%der%dim > 3) then
821 message(1) = "Direct sum Poisson solver only available for 1, 2, or 3 dimensions."
822 call messages_fatal(1, namespace=namespace)
823 end if
824 call poisson_solve_direct(this, namespace, pot, rho)
825
827 call poisson_cg1(namespace, der, this%corrector, pot, rho)
828
830 safe_allocate(rho_corrected(1:der%mesh%np))
831 safe_allocate(vh_correction(1:der%mesh%np_part))
832
833 call correct_rho(this%corrector, der, rho, rho_corrected, vh_correction)
834
835 pot(1:der%mesh%np) = pot(1:der%mesh%np) - vh_correction(1:der%mesh%np)
836 call poisson_cg2(namespace, der, pot, rho_corrected)
837 pot(1:der%mesh%np) = pot(1:der%mesh%np) + vh_correction(1:der%mesh%np)
838
839 safe_deallocate_a(rho_corrected)
840 safe_deallocate_a(vh_correction)
841
842 case (poisson_multigrid)
843 call poisson_multigrid_solver(this%mg, namespace, der, pot, rho)
844
845 case (poisson_fft)
846 if (this%kernel /= poisson_fft_kernel_corrected) then
847 call dpoisson_fft_solve(this%fft_solver, der%mesh, this%cube, pot, rho, this%mesh_cube_map, kernel=kernel)
848 else
849 safe_allocate(rho_corrected(1:der%mesh%np))
850 safe_allocate(vh_correction(1:der%mesh%np_part))
851
852 call correct_rho(this%corrector, der, rho, rho_corrected, vh_correction)
853 call dpoisson_fft_solve(this%fft_solver, der%mesh, this%cube, pot, rho_corrected, this%mesh_cube_map, &
854 average_to_zero = .true., kernel=kernel)
855
856 pot(1:der%mesh%np) = pot(1:der%mesh%np) + vh_correction(1:der%mesh%np)
857 safe_deallocate_a(rho_corrected)
858 safe_deallocate_a(vh_correction)
859 end if
860
862 call poisson_isf_solve(this%isf_solver, der%mesh, this%cube, pot, rho, all_nodes_value)
863
864
865 case (poisson_psolver)
866 if (this%psolver_solver%datacode == "G") then
867 ! Global version
868 call poisson_psolver_global_solve(this%psolver_solver, der%mesh, this%cube, pot, rho)
869 else ! "D" Distributed version
870 call poisson_psolver_parallel_solve(this%psolver_solver, der%mesh, this%cube, pot, rho, this%mesh_cube_map)
871 end if
872
873 case (poisson_no)
874 call poisson_no_solve(this%no_solver, der%mesh, pot, rho)
875 end select
876
877
878 ! Add extra terms for dressed interaction
879 if (this%is_dressed .and. this%method /= poisson_no) then
880 call photon_mode_add_poisson_terms(this%photons, der%mesh, rho, pot)
881 end if
882
883 pop_sub(dpoisson_solve)
884 call profiling_out('POISSON_SOLVE')
885 end subroutine dpoisson_solve
886
887 !-----------------------------------------------------------------
888 subroutine poisson_init_sm(this, namespace, space, main, der, sm, grp, method, force_cmplx)
889 type(poisson_t), intent(inout) :: this
890 type(namespace_t), intent(in) :: namespace
891 class(space_t), intent(in) :: space
892 type(poisson_t), intent(in) :: main
893 type(derivatives_t), target, intent(in) :: der
894 type(submesh_t), intent(inout) :: sm
895 type(mpi_grp_t), intent(in) :: grp
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, grp%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 = grp
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:403
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
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
logical pure function, public multicomm_strategy_is_parallel(mc, level)
Definition: multicomm.F90:728
logical pure function, public multicomm_have_slaves(this)
Definition: multicomm.F90:854
Some general things and nomenclature:
Definition: par_vec.F90:173
subroutine, public photon_mode_compute_dipoles(this, mesh)
Computes the polarization dipole.
subroutine, public photon_mode_add_poisson_terms(this, mesh, rho, pot)
subroutine, public photon_mode_end(this)
subroutine, public photon_mode_set_n_electrons(this, qtot)
subroutine, public photon_mode_init(this, namespace, dim, photon_free)
real(real64), public threshold
Definition: poisson_cg.F90:141
subroutine, public poisson_cg2(namespace, der, pot, rho)
Definition: poisson_cg.F90: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:164
subroutine, public poisson_no_end(this)
Definition: poisson_no.F90:152
subroutine, public zpoisson_solve_sm(this, namespace, sm, pot, rho, all_nodes)
Calculates the Poisson equation. Given the density returns the corresponding potential.
Definition: poisson.F90:2181
integer, parameter, public poisson_multigrid
Definition: poisson.F90:188
subroutine poisson_kernel_init(this, namespace, space, mc, stencil)
Definition: poisson.F90:1239
integer, parameter, public poisson_psolver
Definition: poisson.F90:188
subroutine, public dpoisson_solve_start(this, rho)
Definition: poisson.F90:2002
integer, parameter cmd_finish
Definition: poisson.F90:224
subroutine, public zpoisson_solve_finish(this, pot)
Definition: poisson.F90:2169
subroutine poisson_solve_direct(this, namespace, pot, rho)
Definition: poisson.F90:1448
integer, parameter, public poisson_fft
Definition: poisson.F90:188
subroutine, public zpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Definition: poisson.F90:781
subroutine, public poisson_init_sm(this, namespace, space, main, der, sm, grp, method, force_cmplx)
Definition: poisson.F90:969
subroutine, public poisson_solve_batch(this, namespace, potb, rhob, all_nodes, kernel)
Definition: poisson.F90:827
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:2022
subroutine zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes, kernel)
Definition: poisson.F90:732
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:862
integer, parameter cmd_poisson_solve
Definition: poisson.F90:224
integer, parameter, public poisson_cg
Definition: poisson.F90:188
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:2010
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx)
Definition: poisson.F90:232
subroutine, public zpoisson_solve_start(this, rho)
Definition: poisson.F90:2161
subroutine, public poisson_async_end(this, mc)
Definition: poisson.F90:1094
integer, parameter, public poisson_cg_corrected
Definition: poisson.F90:188
integer, parameter, public poisson_isf
Definition: poisson.F90:188
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:188
integer, parameter, public poisson_no
Definition: poisson.F90:188
logical pure function, public poisson_is_async(this)
Definition: poisson.F90:1118
subroutine, public poisson_end(this)
Definition: poisson.F90:679
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:932
subroutine, public submesh_get_cube_dim(sm, space, db)
finds the dimension of a box containing the submesh
Definition: submesh.F90:897
type(type_t), parameter, 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
This is defined even when running serial.
Definition: mpi.F90:144
A submesh is a type of mesh, used for the projectors in the pseudopotentials It contains points on a ...
Definition: submesh.F90:174
int true(void)