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 integer :: ip
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 !$omp parallel do
690 do ip = 1, der%mesh%np
691 pot(ip) = pot(ip) + m_zi*aux2(ip)
692 end do
693 !$omp end parallel do
694
695 safe_deallocate_a(aux1)
696 safe_deallocate_a(aux2)
697
698 call profiling_out('POISSON_RE_IM_SOLVE')
699
702
703 !-----------------------------------------------------------------
704
705 subroutine zpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
706 type(poisson_t), intent(in) :: this
707 type(namespace_t), intent(in) :: namespace
708 complex(real64), contiguous, intent(inout) :: pot(:)
709 complex(real64), contiguous, intent(in) :: rho(:)
710 logical, optional, intent(in) :: all_nodes
711 type(fourier_space_op_t), optional, intent(in) :: kernel
712 logical, optional, intent(in) :: reset
713
714 logical :: all_nodes_value
715
716 push_sub(zpoisson_solve)
717
718 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
719
720 assert(ubound(pot, dim = 1) == this%der%mesh%np_part .or. ubound(pot, dim = 1) == this%der%mesh%np)
721 assert(ubound(rho, dim = 1) == this%der%mesh%np_part .or. ubound(rho, dim = 1) == this%der%mesh%np)
722
723 assert(this%method /= poisson_null)
724
725 if (poisson_solver_is_iterative(this) .and. optional_default(reset, .true.)) then
726 pot(1:this%der%mesh%np) = m_zero
727 end if
728
729 if (this%method == poisson_fft .and. this%kernel /= poisson_fft_kernel_corrected &
730 .and. .not. this%is_dressed) then
731 !The default (real) Poisson solver is used for OEP and Sternheimer calls were we do not need
732 !a complex-to-xomplex FFT as these parts use the normal Coulomb potential
733 if (this%cube%fft%type == fft_complex) then
734 !We add the profiling here, as the other path uses dpoisson_solve
735 call profiling_in('ZPOISSON_SOLVE')
736 call zpoisson_fft_solve(this%fft_solver, this%der%mesh, this%cube, pot, rho, this%mesh_cube_map, kernel=kernel)
737 call profiling_out('ZPOISSON_SOLVE')
738 else
739 call zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes_value, kernel=kernel)
740 end if
741 else
742 call zpoisson_solve_real_and_imag_separately(this, namespace, pot, rho, all_nodes_value, kernel = kernel)
743 end if
744
745 pop_sub(zpoisson_solve)
746 end subroutine zpoisson_solve
747
748
749 !-----------------------------------------------------------------
750
751 subroutine poisson_solve_batch(this, namespace, potb, rhob, all_nodes, kernel)
752 type(poisson_t), intent(inout) :: this
753 type(namespace_t), intent(in) :: namespace
754 type(batch_t), intent(inout) :: potb
755 type(batch_t), intent(inout) :: rhob
756 logical, optional, intent(in) :: all_nodes
757 type(fourier_space_op_t), optional, intent(in) :: kernel
758
759 integer :: ii
760
761 push_sub(poisson_solve_batch)
762
763 assert(potb%nst_linear == rhob%nst_linear)
764 assert(potb%type() == rhob%type())
765
766 if (potb%type() == type_float) then
767 do ii = 1, potb%nst_linear
768 call dpoisson_solve(this, namespace, potb%dff_linear(:, ii), rhob%dff_linear(:, ii), all_nodes, kernel=kernel)
769 end do
770 else
771 do ii = 1, potb%nst_linear
772 call zpoisson_solve(this, namespace, potb%zff_linear(:, ii), rhob%zff_linear(:, ii), all_nodes, kernel=kernel)
773 end do
774 end if
775
776 pop_sub(poisson_solve_batch)
777 end subroutine poisson_solve_batch
778
779 !-----------------------------------------------------------------
780
786 subroutine dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
787 type(poisson_t), intent(in) :: this
788 type(namespace_t), intent(in) :: namespace
789 real(real64), contiguous, intent(inout) :: pot(:)
790 real(real64), contiguous, intent(in) :: rho(:)
794 logical, optional, intent(in) :: all_nodes
795 type(fourier_space_op_t), optional, intent(in) :: kernel
796 logical, optional, intent(in) :: reset
797
798 type(derivatives_t), pointer :: der
799 real(real64), allocatable :: rho_corrected(:), vh_correction(:)
800 logical :: all_nodes_value
801
802 call profiling_in('POISSON_SOLVE')
803 push_sub(dpoisson_solve)
804
805 der => this%der
806
807 assert(ubound(pot, dim = 1) == der%mesh%np_part .or. ubound(pot, dim = 1) == der%mesh%np)
808 assert(ubound(rho, dim = 1) == der%mesh%np_part .or. ubound(rho, dim = 1) == der%mesh%np)
809
810 ! Check optional argument and set to default if necessary.
811 all_nodes_value = optional_default(all_nodes, this%all_nodes_default)
812
813 if (poisson_solver_is_iterative(this) .and. optional_default(reset, .true.)) then
814 pot(1:der%mesh%np) = m_zero
815 end if
816
817 assert(this%method /= poisson_null)
818
819 if (present(kernel)) then
820 assert(this%method == poisson_fft)
821 end if
822
823 select case (this%method)
824 case (poisson_direct_sum)
825 if ((this%is_dressed .and. this%der%dim - 1 > 3) .or. this%der%dim > 3) then
826 message(1) = "Direct sum Poisson solver only available for 1, 2, or 3 dimensions."
827 call messages_fatal(1, namespace=namespace)
828 end if
829 call poisson_solve_direct(this, namespace, pot, rho)
830
832 call poisson_cg1(namespace, der, this%corrector, pot, rho)
833
835 safe_allocate(rho_corrected(1:der%mesh%np))
836 safe_allocate(vh_correction(1:der%mesh%np_part))
837
838 call correct_rho(this%corrector, der, rho, rho_corrected, vh_correction)
839
840 call lalg_axpy(der%mesh%np, -m_one, vh_correction, pot)
841 call poisson_cg2(namespace, der, pot, rho_corrected)
842 call lalg_axpy(der%mesh%np, m_one, vh_correction, pot)
843
844 safe_deallocate_a(rho_corrected)
845 safe_deallocate_a(vh_correction)
846
847 case (poisson_multigrid)
848 call poisson_multigrid_solver(this%mg, namespace, der, pot, rho)
849
850 case (poisson_fft)
851 if (this%kernel /= poisson_fft_kernel_corrected) then
852 call dpoisson_fft_solve(this%fft_solver, der%mesh, this%cube, pot, rho, this%mesh_cube_map, kernel=kernel)
853 else
854 safe_allocate(rho_corrected(1:der%mesh%np))
855 safe_allocate(vh_correction(1:der%mesh%np_part))
856
857 call correct_rho(this%corrector, der, rho, rho_corrected, vh_correction)
858 call dpoisson_fft_solve(this%fft_solver, der%mesh, this%cube, pot, rho_corrected, this%mesh_cube_map, &
859 average_to_zero = .true., kernel=kernel)
860
861 call lalg_axpy(der%mesh%np, m_one, vh_correction, pot)
862 safe_deallocate_a(rho_corrected)
863 safe_deallocate_a(vh_correction)
864 end if
865
867 call poisson_isf_solve(this%isf_solver, der%mesh, this%cube, pot, rho, all_nodes_value)
868
869
870 case (poisson_psolver)
871 if (this%psolver_solver%datacode == "G") then
872 ! Global version
873 call poisson_psolver_global_solve(this%psolver_solver, der%mesh, this%cube, pot, rho)
874 else ! "D" Distributed version
875 call poisson_psolver_parallel_solve(this%psolver_solver, der%mesh, this%cube, pot, rho, this%mesh_cube_map)
876 end if
877
878 case (poisson_no)
879 call poisson_no_solve(this%no_solver, der%mesh, pot, rho)
880 end select
881
882
883 ! Add extra terms for dressed interaction
884 if (this%is_dressed .and. this%method /= poisson_no) then
885 call photon_mode_add_poisson_terms(this%photons, der%mesh, rho, pot)
886 end if
887
888 pop_sub(dpoisson_solve)
889 call profiling_out('POISSON_SOLVE')
890 end subroutine dpoisson_solve
891
892 !-----------------------------------------------------------------
893 subroutine poisson_init_sm(this, namespace, space, main, der, sm, grp, method, force_cmplx)
894 type(poisson_t), intent(inout) :: this
895 type(namespace_t), intent(in) :: namespace
896 class(space_t), intent(in) :: space
897 type(poisson_t), intent(in) :: main
898 type(derivatives_t), target, intent(in) :: der
899 type(submesh_t), intent(inout) :: sm
900 type(mpi_grp_t), intent(in) :: grp
901 integer, optional, intent(in) :: method
902 logical, optional, intent(in) :: force_cmplx
903
904 integer :: default_solver, idir, iter, maxl
905 integer :: box(space%dim)
906 real(real64) :: qq(der%dim), threshold
907
908 if (this%method /= poisson_null) return ! already initialized
909
910 push_sub(poisson_init_sm)
911
912 this%is_dressed = .false.
913 !TODO: To be implemented as an option
914 this%all_nodes_default = .false.
915
916 this%nslaves = 0
917 this%der => der
918
919#ifdef HAVE_MPI
920 this%all_nodes_default = main%all_nodes_default
921#endif
922
923 default_solver = poisson_direct_sum
924 this%method = default_solver
925 if (present(method)) this%method = method
926
927 if (der%mesh%use_curvilinear) then
928 call messages_not_implemented("Submesh Poisson solver with curvilinear mesh", namespace=namespace)
929 end if
930
931 this%kernel = poisson_fft_kernel_none
932
933 select case (this%method)
934 case (poisson_direct_sum)
935 !Nothing to be done
936
937 case (poisson_isf)
938 !TODO: Add support for domain parrallelization
939 assert(.not. der%mesh%parallel_in_domains)
940 call submesh_get_cube_dim(sm, space, box)
941 call submesh_init_cube_map(sm, space)
942 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
943 fft_type = fft_none, need_partition=.not.der%mesh%parallel_in_domains)
944 call cube_init_cube_map(this%cube, sm%mesh)
945 call poisson_isf_init(this%isf_solver, namespace, der%mesh, this%cube, grp%comm, init_world = this%all_nodes_default)
946
947 case (poisson_psolver)
948 !TODO: Add support for domain parrallelization
949 assert(.not. der%mesh%parallel_in_domains)
950 if (this%all_nodes_default) then
951 this%cube%mpi_grp = grp
952 else
953 this%cube%mpi_grp = this%der%mesh%mpi_grp
954 end if
955 call submesh_get_cube_dim(sm, space, box)
956 call submesh_init_cube_map(sm, space)
957 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
958 fft_type = fft_none, need_partition=.not.der%mesh%parallel_in_domains)
959 call cube_init_cube_map(this%cube, sm%mesh)
960 qq = m_zero
961 call poisson_psolver_init(this%psolver_solver, namespace, space, this%cube, m_zero, qq, force_isolated=.true.)
962 call poisson_psolver_get_dims(this%psolver_solver, this%cube)
963 case (poisson_fft)
964 !Here we impose zero boundary conditions
965 this%kernel = poisson_fft_kernel_sph
966 !We need to parse this, in case this routine is called before poisson_init
967 call parse_variable(namespace, 'FFTLibrary', fftlib_fftw, fft_default_lib)
968
969 call submesh_get_cube_dim(sm, space, box)
970 call submesh_init_cube_map(sm, space)
971 !We double the size of the cell
972 !Maybe the factor of two should be controlled as a variable
973 do idir = 1, space%dim
974 box(idir) = (2 * (box(idir) - 1)) + 1
975 end do
976 if (optional_default(force_cmplx, .false.)) then
977 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
978 fft_type = fft_complex, need_partition=.not.der%mesh%parallel_in_domains)
979 else
980 call cube_init(this%cube, box, namespace, space, sm%mesh%spacing, sm%mesh%coord_system, &
981 fft_type = fft_real, need_partition=.not.der%mesh%parallel_in_domains)
982 end if
983 call poisson_fft_init(this%fft_solver, namespace, space, this%cube, this%kernel)
984 case (poisson_cg)
985 call parse_variable(namespace, 'PoissonSolverMaxMultipole', 4, maxl)
986 write(message(1),'(a,i2)')'Info: Boundary conditions fixed up to L =', maxl
987 call messages_info(1, namespace=namespace)
988 call parse_variable(namespace, 'PoissonSolverMaxIter', 500, iter)
989 call parse_variable(namespace, 'PoissonSolverThreshold', 1.0e-6_real64, threshold)
990 call poisson_corrections_init(this%corrector, namespace, space, maxl, this%der%mesh)
991 call poisson_cg_init(threshold, iter)
992 end select
993
994 pop_sub(poisson_init_sm)
995 end subroutine poisson_init_sm
996
997 ! -----------------------------------------------------------------
998
999 logical pure function poisson_solver_is_iterative(this) result(iterative)
1000 type(poisson_t), intent(in) :: this
1001
1002 iterative = this%method == poisson_cg .or. this%method == poisson_cg_corrected
1003 end function poisson_solver_is_iterative
1004
1005 !-----------------------------------------------------------------
1006 subroutine poisson_async_init(this, mc)
1007 type(poisson_t), intent(inout) :: this
1008 type(multicomm_t), intent(in) :: mc
1009
1010 push_sub(poisson_async_init)
1011
1012#ifdef HAVE_MPI
1013 if (multicomm_have_slaves(mc)) then
1014
1015 call mpi_grp_init(this%local_grp, mc%group_comm(p_strategy_states))
1016
1017 this%root = (this%local_grp%is_root())
1018
1019 this%intercomm = mc%slave_intercomm
1020 call mpi_comm_remote_size(this%intercomm, this%nslaves)
1021
1022 end if
1023#endif
1024
1025 pop_sub(poisson_async_init)
1026
1027 end subroutine poisson_async_init
1028
1029 !-----------------------------------------------------------------
1030
1031 subroutine poisson_async_end(this, mc)
1032 type(poisson_t), intent(inout) :: this
1033 type(multicomm_t), intent(in) :: mc
1034
1035#ifdef HAVE_MPI
1036 integer :: islave
1037#endif
1038
1039 push_sub(poisson_async_end)
1040
1041#ifdef HAVE_MPI
1042 if (multicomm_have_slaves(mc)) then
1043
1044 ! send the finish signal
1045 do islave = this%local_grp%rank, this%nslaves - 1, this%local_grp%size
1046 call mpi_send(m_one, 1, mpi_double_precision, islave, cmd_finish, this%intercomm)
1047 end do
1048
1049 end if
1050#endif
1051
1052 pop_sub(poisson_async_end)
1053
1054 end subroutine poisson_async_end
1055
1056 !-----------------------------------------------------------------
1057
1058 subroutine poisson_slave_work(this, namespace)
1059 type(poisson_t), intent(inout) :: this
1060 type(namespace_t), intent(in) :: namespace
1061
1062#ifdef HAVE_MPI
1063 real(real64), allocatable :: rho(:), pot(:)
1064 logical :: done
1065 type(mpi_status) :: status
1066 integer :: bcast_root
1067
1068 push_sub(poisson_slave_work)
1069 call profiling_in("SLAVE_WORK")
1070
1071 safe_allocate(rho(1:this%der%mesh%np))
1072 safe_allocate(pot(1:this%der%mesh%np))
1073 done = .false.
1074
1075 do while(.not. done)
1076
1077 call profiling_in("SLAVE_WAIT")
1078 call mpi_recv(rho(1), this%der%mesh%np, mpi_double_precision, mpi_any_source, mpi_any_tag, this%intercomm, status)
1079 call profiling_out("SLAVE_WAIT")
1080
1081 ! The tag of the message tells us what we have to do.
1082 select case (status%MPI_TAG)
1083
1084 case (cmd_finish)
1085 done = .true.
1087 case (cmd_poisson_solve)
1088 call dpoisson_solve(this, namespace, pot, rho)
1089
1090 call profiling_in("SLAVE_BROADCAST")
1091 bcast_root = mpi_proc_null
1092 if (this%root) bcast_root = mpi_root
1093 call mpi_bcast(pot(1), this%der%mesh%np, mpi_double_precision, bcast_root, this%intercomm)
1094 call profiling_out("SLAVE_BROADCAST")
1095
1096 end select
1097
1098 end do
1099
1100 safe_deallocate_a(pot)
1101 safe_deallocate_a(rho)
1102
1103 call profiling_out("SLAVE_WORK")
1104 pop_sub(poisson_slave_work)
1105#endif
1106 end subroutine poisson_slave_work
1107
1108 !----------------------------------------------------------------
1109
1110 logical pure function poisson_is_async(this) result(async)
1111 type(poisson_t), intent(in) :: this
1112
1113 async = (this%nslaves > 0)
1115 end function poisson_is_async
1116
1117 !----------------------------------------------------------------
1118
1119 subroutine poisson_build_kernel(this, namespace, space, coulb, qq, cam, singul)
1120 type(poisson_t), intent(in) :: this
1121 type(namespace_t), intent(in) :: namespace
1122 class(space_t), intent(in) :: space
1123 type(fourier_space_op_t), intent(inout) :: coulb
1124 real(real64), intent(in) :: qq(:)
1125 type(xc_cam_t), intent(in) :: cam
1126 real(real64), optional, intent(in) :: singul
1127
1128 real(real64), parameter :: vanishing_q = 1.0e-5_real64
1129 logical :: reinit
1130
1132
1133 if (space%is_periodic()) then
1134 assert(ubound(qq, 1) >= space%periodic_dim)
1135 assert(this%method == poisson_fft)
1136 end if
1137
1138 if (cam%omega > m_epsilon) then
1139 if (this%method /= poisson_fft) then
1140 write(message(1),'(a)') "Poisson solver with range separation is only implemented with FFT."
1141 call messages_fatal(1, namespace=namespace)
1142 end if
1143 end if
1144
1145 !We only reinitialize the poisson solver if needed
1146 reinit = .false.
1147 if (allocated(coulb%qq)) then
1148 reinit = any(abs(coulb%qq(1:space%periodic_dim) - qq(1:space%periodic_dim)) > m_epsilon)
1149 end if
1150 reinit = reinit .or. (abs(coulb%mu - cam%omega) > m_epsilon .and. cam%omega > m_epsilon)
1151 reinit = reinit .or. (abs(coulb%alpha - cam%alpha) > m_epsilon .and. cam%alpha > m_epsilon)
1152 reinit = reinit .or. (abs(coulb%beta - cam%beta) > m_epsilon .and. cam%beta > m_epsilon)
1153
1154 if (reinit) then
1155 !TODO: this should be a select case supporting other kernels.
1156 ! This means that we need an abstract object for kernels.
1157 select case (this%method)
1158 case (poisson_fft)
1159 ! Check that we are consistent: the Poisson solver supports must return 1 here
1160 assert(is_close(poisson_get_full_range_weight(this, cam), m_one))
1161
1162 call fourier_space_op_end(coulb)
1163
1164 safe_allocate(coulb%qq(1:space%dim))
1165 coulb%qq(1:space%periodic_dim) = qq(1:space%periodic_dim)
1166 coulb%qq(space%periodic_dim+1:space%dim) = vanishing_q
1167 !We must define the singularity if we specify a q vector and we do not use the short-range Coulomb potential
1168 coulb%singularity = optional_default(singul, m_zero)
1169 coulb%mu = cam%omega
1170 coulb%alpha = cam%alpha
1171 coulb%beta = cam%beta
1172 call poisson_fft_get_kernel(namespace, space, this%cube, coulb, this%kernel, &
1173 this%poisson_soft_coulomb_param)
1174 case default
1175 call messages_not_implemented("poisson_build_kernel with other methods than FFT", namespace=namespace)
1176 end select
1177 end if
1178
1179 pop_sub(poisson_build_kernel)
1180 end subroutine poisson_build_kernel
1181
1182 !----------------------------------------------------------------
1191 real(real64) function poisson_get_full_range_weight(this, cam) result(weight)
1192 type(poisson_t), intent(in) :: this
1193 type(xc_cam_t), intent(in) :: cam
1194
1195 select case (this%method)
1196 case (poisson_fft)
1197 weight = m_one
1198 case default
1199 if(cam%omega < m_epsilon) then
1200 weight = cam%alpha
1201 else if(cam%alpha > m_epsilon .and. cam%beta < m_epsilon) then
1202 weight = cam%alpha
1203 else if(cam%alpha < m_epsilon .and. cam%beta > m_epsilon) then
1204 weight = cam%beta
1205 else
1206 assert(.false.)
1207 end if
1208 end select
1210
1211#include "poisson_init_inc.F90"
1212#include "poisson_direct_inc.F90"
1213#include "poisson_direct_sm_inc.F90"
1214
1215#include "undef.F90"
1216#include "real.F90"
1217#include "poisson_inc.F90"
1218#include "undef.F90"
1219#include "complex.F90"
1220#include "poisson_inc.F90"
1221
1222end module poisson_oct_m
1223
1224!! Local Variables:
1225!! mode: f90
1226!! coding: utf-8
1227!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:173
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:231
subroutine, public poisson_cg1(namespace, der, corrector, pot, rho)
Definition: poisson_cg.F90:167
subroutine, public poisson_cg_init(thr, itr)
Definition: poisson_cg.F90:149
subroutine, public poisson_cg_end
Definition: poisson_cg.F90:161
subroutine, public poisson_corrections_end(this)
subroutine, public poisson_corrections_init(this, namespace, space, ml, mesh)
subroutine, public correct_rho(this, der, rho, rho_corrected, vh_correction)
integer, parameter, public poisson_fft_kernel_nocut
integer, parameter, public poisson_fft_kernel_cyl
subroutine, public zpoisson_fft_solve(this, mesh, cube, pot, rho, mesh_cube_map, average_to_zero, kernel, sm)
subroutine, public poisson_fft_end(this)
subroutine, public poisson_fft_init(this, namespace, space, cube, kernel, soft_coulb_param, fullcube)
integer, parameter, public poisson_fft_kernel_pla
integer, parameter, public poisson_fft_kernel_none
integer, parameter, public poisson_fft_kernel_corrected
integer, parameter, public poisson_fft_kernel_sph
subroutine, public dpoisson_fft_solve(this, mesh, cube, pot, rho, mesh_cube_map, average_to_zero, kernel, sm)
subroutine, public poisson_isf_end(this)
subroutine, public poisson_isf_init(this, namespace, mesh, cube, all_nodes_comm, init_world)
subroutine, public poisson_isf_solve(this, mesh, cube, pot, rho, all_nodes, sm)
subroutine, public poisson_multigrid_solver(this, namespace, der, pot, rho)
A multigrid Poisson solver with corrections at the boundaries.
subroutine, public poisson_multigrid_end(this)
subroutine, public poisson_no_solve(this, mesh, pot, rho)
Definition: poisson_no.F90:164
subroutine, public poisson_no_end(this)
Definition: poisson_no.F90:152
subroutine, public zpoisson_solve_sm(this, namespace, sm, pot, rho, all_nodes)
Calculates the Poisson equation. Given the density returns the corresponding potential.
Definition: poisson.F90:2186
integer, parameter, public poisson_multigrid
Definition: poisson.F90:188
subroutine poisson_kernel_init(this, namespace, space, mc, stencil)
Definition: poisson.F90:1244
integer, parameter, public poisson_psolver
Definition: poisson.F90:188
subroutine, public dpoisson_solve_start(this, rho)
Definition: poisson.F90:2007
integer, parameter cmd_finish
Definition: poisson.F90:224
subroutine, public zpoisson_solve_finish(this, pot)
Definition: poisson.F90:2174
subroutine poisson_solve_direct(this, namespace, pot, rho)
Definition: poisson.F90:1453
integer, parameter, public poisson_fft
Definition: poisson.F90:188
subroutine, public zpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Definition: poisson.F90:786
subroutine, public poisson_init_sm(this, namespace, space, main, der, sm, grp, method, force_cmplx)
Definition: poisson.F90:974
subroutine, public poisson_solve_batch(this, namespace, potb, rhob, all_nodes, kernel)
Definition: poisson.F90:832
subroutine, public poisson_async_init(this, mc)
Definition: poisson.F90:1087
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:2027
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:1080
subroutine, public poisson_slave_work(this, namespace)
Definition: poisson.F90:1115
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:867
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:1132
subroutine, public dpoisson_solve_finish(this, pot)
Definition: poisson.F90:2015
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:2166
subroutine, public poisson_async_end(this, mc)
Definition: poisson.F90:1099
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:1204
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:1123
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)