LCOV - code coverage report
Current view: top level - src - ewald_environment_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:cccd2f3) Lines: 95.7 % 234 224
Test Date: 2026-05-06 07:07:47 Functions: 90.0 % 10 9

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \par History
      10              : !>      JGH FEB-13-2007 : Distributed/replicated realspace grids
      11              : !>      Teodoro Laino [tlaino] - University of Zurich - 12.2007
      12              : !> \author CJM NOV-30-2003
      13              : ! **************************************************************************************************
      14              : MODULE ewald_environment_types
      15              :    USE cell_types,                      ONLY: use_perd_none,&
      16              :                                               use_perd_x,&
      17              :                                               use_perd_xy,&
      18              :                                               use_perd_xyz,&
      19              :                                               use_perd_xz,&
      20              :                                               use_perd_y,&
      21              :                                               use_perd_yz,&
      22              :                                               use_perd_z
      23              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      24              :                                               cp_logger_type
      25              :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      26              :                                               cp_print_key_unit_nr
      27              :    USE cp_units,                        ONLY: cp_unit_from_cp2k
      28              :    USE input_cp2k_poisson,              ONLY: create_ewald_section
      29              :    USE input_enumeration_types,         ONLY: enum_i2c,&
      30              :                                               enumeration_type
      31              :    USE input_keyword_types,             ONLY: keyword_get,&
      32              :                                               keyword_type
      33              :    USE input_section_types,             ONLY: section_get_keyword,&
      34              :                                               section_release,&
      35              :                                               section_type,&
      36              :                                               section_vals_get_subs_vals,&
      37              :                                               section_vals_release,&
      38              :                                               section_vals_retain,&
      39              :                                               section_vals_type,&
      40              :                                               section_vals_val_get
      41              :    USE kinds,                           ONLY: dp
      42              :    USE mathconstants,                   ONLY: twopi
      43              :    USE mathlib,                         ONLY: det_3x3
      44              :    USE message_passing,                 ONLY: mp_comm_type,&
      45              :                                               mp_para_env_release,&
      46              :                                               mp_para_env_type
      47              :    USE pw_grid_info,                    ONLY: pw_grid_n_for_fft
      48              :    USE pw_poisson_types,                ONLY: do_ewald_ewald,&
      49              :                                               do_ewald_none,&
      50              :                                               do_ewald_pme,&
      51              :                                               do_ewald_spme
      52              : #include "./base/base_uses.f90"
      53              : 
      54              :    IMPLICIT NONE
      55              :    PRIVATE
      56              : 
      57              : ! **************************************************************************************************
      58              : !> \brief to build arrays of pointers
      59              : !> \param ewald_env the pointer to the ewald_env
      60              : !> \par History
      61              : !>      11/03
      62              : !> \author CJM
      63              : ! **************************************************************************************************
      64              :    TYPE ewald_environment_type
      65              :       PRIVATE
      66              :       LOGICAL   :: do_multipoles = .FALSE. ! Flag for using the multipole code
      67              :       INTEGER   :: do_ipol = -1 ! Solver for induced dipoles
      68              :       INTEGER   :: max_multipole = -1 ! max expansion in the multipoles
      69              :       INTEGER   :: max_ipol_iter = -1 ! max number of interaction for induced dipoles
      70              :       INTEGER   :: ewald_type = -1 ! type of ewald
      71              :       INTEGER   :: gmax(3) = -1 ! max Miller index
      72              :       INTEGER   :: ns_max = -1 ! # grid points for small grid (PME)
      73              :       INTEGER   :: o_spline = -1 ! order of spline (SPME)
      74              :       REAL(KIND=dp) :: precs = 0.0_dp ! precision achieved when evaluating the real-space part
      75              :       REAL(KIND=dp) :: alpha = 0.0_dp, rcut = 0.0_dp ! ewald alpha and real-space cutoff
      76              :       REAL(KIND=dp) :: epsilon = 0.0_dp ! tolerance for small grid (PME)
      77              :       REAL(KIND=dp) :: eps_pol = 0.0_dp ! tolerance for convergence of induced dipoles
      78              :       TYPE(mp_para_env_type), POINTER          :: para_env => NULL()
      79              :       TYPE(section_vals_type), POINTER         :: poisson_section => NULL()
      80              :       ! interaction cutoff is required to make the electrostatic interaction
      81              :       ! continuous at a pair distance equal to rcut. this is ignored by the
      82              :       ! multipole code and is otherwise only active when SHIFT_CUTOFF is used.
      83              :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: interaction_cutoffs => NULL()
      84              :       ! store current cell, used to rebuild lazily.
      85              :       REAL(KIND=dp), DIMENSION(3, 3)          :: cell_hmat = -1.0_dp
      86              :    END TYPE ewald_environment_type
      87              : 
      88              : ! *** Public data types ***
      89              :    PUBLIC :: ewald_environment_type
      90              : 
      91              : ! *** Public subroutines ***
      92              :    PUBLIC :: ewald_env_get, &
      93              :              ewald_env_set, &
      94              :              ewald_env_create, &
      95              :              ewald_env_release, &
      96              :              read_ewald_section, &
      97              :              read_ewald_section_tb
      98              : 
      99              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ewald_environment_types'
     100              : 
     101              : CONTAINS
     102              : 
     103              : ! **************************************************************************************************
     104              : !> \brief Purpose: Get the EWALD environment.
     105              : !> \param ewald_env the pointer to the ewald_env
     106              : !> \param ewald_type ...
     107              : !> \param alpha ...
     108              : !> \param eps_pol ...
     109              : !> \param epsilon ...
     110              : !> \param gmax ...
     111              : !> \param ns_max ...
     112              : !> \param o_spline ...
     113              : !> \param group ...
     114              : !> \param para_env ...
     115              : !> \param poisson_section ...
     116              : !> \param precs ...
     117              : !> \param rcut ...
     118              : !> \param do_multipoles ...
     119              : !> \param max_multipole ...
     120              : !> \param do_ipol ...
     121              : !> \param max_ipol_iter ...
     122              : !> \param interaction_cutoffs ...
     123              : !> \param cell_hmat ...
     124              : !> \par History
     125              : !>      11/03
     126              : !> \author CJM
     127              : ! **************************************************************************************************
     128       557347 :    SUBROUTINE ewald_env_get(ewald_env, ewald_type, alpha, eps_pol, epsilon, &
     129              :                             gmax, ns_max, o_spline, group, para_env, poisson_section, precs, &
     130              :                             rcut, do_multipoles, max_multipole, do_ipol, max_ipol_iter, &
     131              :                             interaction_cutoffs, cell_hmat)
     132              :       TYPE(ewald_environment_type), INTENT(IN)           :: ewald_env
     133              :       INTEGER, OPTIONAL                                  :: ewald_type
     134              :       REAL(KIND=dp), OPTIONAL                            :: alpha, eps_pol, epsilon
     135              :       INTEGER, OPTIONAL                                  :: gmax(3), ns_max, o_spline
     136              :       TYPE(mp_comm_type), INTENT(OUT), OPTIONAL          :: group
     137              :       TYPE(mp_para_env_type), OPTIONAL, POINTER          :: para_env
     138              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: poisson_section
     139              :       REAL(KIND=dp), OPTIONAL                            :: precs, rcut
     140              :       LOGICAL, INTENT(OUT), OPTIONAL                     :: do_multipoles
     141              :       INTEGER, INTENT(OUT), OPTIONAL                     :: max_multipole, do_ipol, max_ipol_iter
     142              :       REAL(KIND=dp), DIMENSION(:, :, :), OPTIONAL, &
     143              :          POINTER                                         :: interaction_cutoffs
     144              :       REAL(KIND=dp), DIMENSION(3, 3), OPTIONAL           :: cell_hmat
     145              : 
     146       557347 :       IF (PRESENT(ewald_type)) ewald_type = ewald_env%ewald_type
     147       557347 :       IF (PRESENT(do_multipoles)) do_multipoles = ewald_env%do_multipoles
     148       557347 :       IF (PRESENT(do_ipol)) do_ipol = ewald_env%do_ipol
     149       557347 :       IF (PRESENT(max_multipole)) max_multipole = ewald_env%max_multipole
     150       557347 :       IF (PRESENT(max_ipol_iter)) max_ipol_iter = ewald_env%max_ipol_iter
     151       557347 :       IF (PRESENT(alpha)) alpha = ewald_env%alpha
     152       557347 :       IF (PRESENT(precs)) precs = ewald_env%precs
     153       557347 :       IF (PRESENT(rcut)) rcut = ewald_env%rcut
     154       557347 :       IF (PRESENT(epsilon)) epsilon = ewald_env%epsilon
     155       557347 :       IF (PRESENT(eps_pol)) eps_pol = ewald_env%eps_pol
     156       574663 :       IF (PRESENT(gmax)) gmax = ewald_env%gmax
     157       557347 :       IF (PRESENT(ns_max)) ns_max = ewald_env%ns_max
     158       557347 :       IF (PRESENT(o_spline)) o_spline = ewald_env%o_spline
     159       557347 :       IF (PRESENT(group)) group = ewald_env%para_env
     160       557347 :       IF (PRESENT(para_env)) para_env => ewald_env%para_env
     161       557347 :       IF (PRESENT(poisson_section)) poisson_section => ewald_env%poisson_section
     162       557347 :       IF (PRESENT(interaction_cutoffs)) interaction_cutoffs => &
     163        81608 :          ewald_env%interaction_cutoffs
     164      1673410 :       IF (PRESENT(cell_hmat)) cell_hmat = ewald_env%cell_hmat
     165       557347 :    END SUBROUTINE ewald_env_get
     166              : 
     167              : ! **************************************************************************************************
     168              : !> \brief Purpose: Set the EWALD environment.
     169              : !> \param ewald_env the pointer to the ewald_env
     170              : !> \param ewald_type ...
     171              : !> \param alpha ...
     172              : !> \param epsilon ...
     173              : !> \param eps_pol ...
     174              : !> \param gmax ...
     175              : !> \param ns_max ...
     176              : !> \param precs ...
     177              : !> \param o_spline ...
     178              : !> \param para_env ...
     179              : !> \param poisson_section ...
     180              : !> \param interaction_cutoffs ...
     181              : !> \param cell_hmat ...
     182              : !> \par History
     183              : !>      11/03
     184              : !> \author CJM
     185              : ! **************************************************************************************************
     186        25438 :    SUBROUTINE ewald_env_set(ewald_env, ewald_type, alpha, epsilon, eps_pol, &
     187              :                             gmax, ns_max, precs, o_spline, para_env, poisson_section, &
     188              :                             interaction_cutoffs, cell_hmat)
     189              : 
     190              :       TYPE(ewald_environment_type), INTENT(INOUT)        :: ewald_env
     191              :       INTEGER, OPTIONAL                                  :: ewald_type
     192              :       REAL(KIND=dp), OPTIONAL                            :: alpha, epsilon, eps_pol
     193              :       INTEGER, OPTIONAL                                  :: gmax(3), ns_max
     194              :       REAL(KIND=dp), OPTIONAL                            :: precs
     195              :       INTEGER, OPTIONAL                                  :: o_spline
     196              :       TYPE(mp_para_env_type), OPTIONAL, POINTER          :: para_env
     197              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: poisson_section
     198              :       REAL(KIND=dp), DIMENSION(:, :, :), OPTIONAL, &
     199              :          POINTER                                         :: interaction_cutoffs
     200              :       REAL(KIND=dp), DIMENSION(3, 3), OPTIONAL           :: cell_hmat
     201              : 
     202        25438 :       IF (PRESENT(ewald_type)) ewald_env%ewald_type = ewald_type
     203        25438 :       IF (PRESENT(alpha)) ewald_env%alpha = alpha
     204        25438 :       IF (PRESENT(precs)) ewald_env%precs = precs
     205        25438 :       IF (PRESENT(epsilon)) ewald_env%epsilon = epsilon
     206        25438 :       IF (PRESENT(eps_pol)) ewald_env%eps_pol = eps_pol
     207        25438 :       IF (PRESENT(gmax)) ewald_env%gmax = gmax
     208        25438 :       IF (PRESENT(ns_max)) ewald_env%ns_max = ns_max
     209        25438 :       IF (PRESENT(o_spline)) ewald_env%o_spline = o_spline
     210        25438 :       IF (PRESENT(para_env)) ewald_env%para_env => para_env
     211        25438 :       IF (PRESENT(poisson_section)) THEN
     212         4321 :          CALL section_vals_retain(poisson_section)
     213         4321 :          CALL section_vals_release(ewald_env%poisson_section)
     214         4321 :          ewald_env%poisson_section => poisson_section
     215              :       END IF
     216        25438 :       IF (PRESENT(interaction_cutoffs)) ewald_env%interaction_cutoffs => &
     217         2647 :          interaction_cutoffs
     218       265548 :       IF (PRESENT(cell_hmat)) ewald_env%cell_hmat = cell_hmat
     219        25438 :    END SUBROUTINE ewald_env_set
     220              : 
     221              : ! **************************************************************************************************
     222              : !> \brief allocates and intitializes a ewald_env
     223              : !> \param ewald_env the object to create
     224              : !> \param para_env ...
     225              : !> \par History
     226              : !>      12.2002 created [fawzi]
     227              : !> \author Fawzi Mohamed
     228              : ! **************************************************************************************************
     229        73457 :    SUBROUTINE ewald_env_create(ewald_env, para_env)
     230              :       TYPE(ewald_environment_type), INTENT(OUT)          :: ewald_env
     231              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     232              : 
     233              :       NULLIFY (ewald_env%poisson_section)
     234         4321 :       CALL para_env%retain()
     235         4321 :       ewald_env%para_env => para_env
     236         4321 :       NULLIFY (ewald_env%interaction_cutoffs) ! allocated and initialized later
     237         4321 :    END SUBROUTINE ewald_env_create
     238              : 
     239              : ! **************************************************************************************************
     240              : !> \brief releases the given ewald_env (see doc/ReferenceCounting.html)
     241              : !> \param ewald_env the object to release
     242              : !> \par History
     243              : !>      12.2002 created [fawzi]
     244              : !> \author Fawzi Mohamed
     245              : ! **************************************************************************************************
     246         4321 :    SUBROUTINE ewald_env_release(ewald_env)
     247              :       TYPE(ewald_environment_type), INTENT(INOUT)        :: ewald_env
     248              : 
     249         4321 :       CALL mp_para_env_release(ewald_env%para_env)
     250         4321 :       CALL section_vals_release(ewald_env%poisson_section)
     251         4321 :       IF (ASSOCIATED(ewald_env%interaction_cutoffs)) THEN
     252         2647 :          DEALLOCATE (ewald_env%interaction_cutoffs)
     253              :       END IF
     254              : 
     255         4321 :    END SUBROUTINE ewald_env_release
     256              : 
     257              : ! **************************************************************************************************
     258              : !> \brief Purpose: read the EWALD section
     259              : !> \param ewald_env the pointer to the ewald_env
     260              : !> \param ewald_section ...
     261              : !> \author Teodoro Laino [tlaino] -University of Zurich - 2005
     262              : ! **************************************************************************************************
     263         3839 :    SUBROUTINE read_ewald_section(ewald_env, ewald_section)
     264              :       TYPE(ewald_environment_type), INTENT(INOUT)        :: ewald_env
     265              :       TYPE(section_vals_type), POINTER                   :: ewald_section
     266              : 
     267              :       INTEGER                                            :: iw
     268         3839 :       INTEGER, DIMENSION(:), POINTER                     :: gmax_read
     269              :       LOGICAL                                            :: explicit
     270              :       REAL(KIND=dp)                                      :: dummy
     271              :       TYPE(cp_logger_type), POINTER                      :: logger
     272              :       TYPE(enumeration_type), POINTER                    :: enum
     273              :       TYPE(keyword_type), POINTER                        :: keyword
     274              :       TYPE(section_type), POINTER                        :: section
     275              :       TYPE(section_vals_type), POINTER                   :: multipole_section
     276              : 
     277         3839 :       NULLIFY (enum, keyword, section, multipole_section)
     278         7678 :       logger => cp_get_default_logger()
     279         3839 :       CALL section_vals_val_get(ewald_section, "EWALD_TYPE", i_val=ewald_env%ewald_type)
     280         3839 :       CALL section_vals_val_get(ewald_section, "ALPHA", r_val=ewald_env%alpha)
     281         3839 :       CALL section_vals_val_get(ewald_section, "EWALD_ACCURACY", r_val=ewald_env%precs)
     282              : 
     283         3839 :       IF (ewald_env%ewald_type == do_ewald_none) THEN
     284         1046 :          ewald_env%rcut = 0.0_dp
     285              :       ELSE
     286         2793 :          CALL section_vals_val_get(ewald_section, "RCUT", explicit=explicit)
     287         2793 :          IF (explicit) THEN
     288            8 :             CALL section_vals_val_get(ewald_section, "RCUT", r_val=ewald_env%rcut)
     289              :          ELSE
     290         2785 :             ewald_env%rcut = find_ewald_optimal_value(ewald_env%precs)/ewald_env%alpha
     291              :          END IF
     292              :       END IF
     293              :       ! we have no defaults for gmax, gmax is only needed for ewald and spme
     294         6546 :       SELECT CASE (ewald_env%ewald_type)
     295              :       CASE (do_ewald_ewald, do_ewald_spme)
     296         2707 :          CALL section_vals_val_get(ewald_section, "GMAX", i_vals=gmax_read)
     297         5098 :          SELECT CASE (SIZE(gmax_read, 1))
     298              :          CASE (1)
     299         9564 :             ewald_env%gmax = gmax_read(1)
     300              :          CASE (3)
     301         1264 :             ewald_env%gmax = gmax_read
     302              :          CASE DEFAULT
     303         2707 :             CPABORT("")
     304              :          END SELECT
     305         2707 :          IF (ewald_env%ewald_type == do_ewald_spme) THEN
     306         1884 :             CALL section_vals_val_get(ewald_section, "O_SPLINE", i_val=ewald_env%o_spline)
     307              :          END IF
     308              :       CASE (do_ewald_pme)
     309           86 :          CALL section_vals_val_get(ewald_section, "NS_MAX", i_val=ewald_env%ns_max)
     310           86 :          CALL section_vals_val_get(ewald_section, "EPSILON", r_val=ewald_env%epsilon)
     311              :       CASE DEFAULT
     312              :          ! this should not be used for do_ewald_none
     313         4184 :          ewald_env%gmax = HUGE(0)
     314         4885 :          ewald_env%ns_max = HUGE(0)
     315              :       END SELECT
     316              : 
     317              :       ! Multipoles
     318         3839 :       multipole_section => section_vals_get_subs_vals(ewald_section, "MULTIPOLES")
     319         3839 :       CALL section_vals_val_get(multipole_section, "_SECTION_PARAMETERS_", l_val=ewald_env%do_multipoles)
     320         3839 :       CALL section_vals_val_get(multipole_section, "POL_SCF", i_val=ewald_env%do_ipol)
     321         3839 :       CALL section_vals_val_get(multipole_section, "EPS_POL", r_val=ewald_env%eps_pol)
     322         3839 :       IF (ewald_env%do_multipoles) THEN
     323          336 :          SELECT CASE (ewald_env%ewald_type)
     324              :          CASE (do_ewald_ewald)
     325              :             CALL section_vals_val_get(multipole_section, "MAX_MULTIPOLE_EXPANSION", &
     326          168 :                                       i_val=ewald_env%max_multipole)
     327          168 :             CALL section_vals_val_get(multipole_section, "MAX_IPOL_ITER", i_val=ewald_env%max_ipol_iter)
     328              :          CASE DEFAULT
     329          168 :             CPABORT("Multipole code works at the moment only with standard EWALD sums.")
     330              :          END SELECT
     331              :       END IF
     332              : 
     333              :       iw = cp_print_key_unit_nr(logger, ewald_section, "PRINT%PROGRAM_RUN_INFO", &
     334         3839 :                                 extension=".log")
     335         3839 :       IF (iw > 0) THEN
     336         1908 :          NULLIFY (keyword, enum)
     337         1908 :          CALL create_ewald_section(section)
     338         1908 :          IF (ewald_env%ewald_type /= do_ewald_none) THEN
     339         1423 :             keyword => section_get_keyword(section, "EWALD_TYPE")
     340         1423 :             CALL keyword_get(keyword, enum=enum)
     341         1423 :             WRITE (iw, '(/,T2,"EWALD| ",A,T67,A14 )') 'Summation is done by:', &
     342         2846 :                ADJUSTR(TRIM(enum_i2c(enum, ewald_env%ewald_type)))
     343         1423 :             IF (ewald_env%do_multipoles) THEN
     344           84 :                NULLIFY (keyword, enum)
     345           84 :                keyword => section_get_keyword(section, "MULTIPOLES%MAX_MULTIPOLE_EXPANSION")
     346           84 :                CALL keyword_get(keyword, enum=enum)
     347           84 :                WRITE (iw, '( T2,"EWALD| ",A )') 'Enabled Multipole Method'
     348           84 :                WRITE (iw, '( T2,"EWALD| ",A,T67,A14 )') 'Max Term in Multipole Expansion :', &
     349          168 :                   ADJUSTR(TRIM(enum_i2c(enum, ewald_env%max_multipole)))
     350           84 :                WRITE (iw, '( T2,"EWALD| ",A,T67,3I10 )') 'Max number Iterations for IPOL :', &
     351          168 :                   ewald_env%max_ipol_iter
     352              :             END IF
     353         1423 :             dummy = cp_unit_from_cp2k(ewald_env%alpha, "angstrom^-1")
     354              :             WRITE (iw, '( T2,"EWALD| ",A,A18,A,T71,F10.4 )') &
     355         1423 :                'Alpha parameter [', 'ANGSTROM^-1', ']', dummy
     356         1423 :             dummy = cp_unit_from_cp2k(ewald_env%rcut, "angstrom")
     357              :             WRITE (iw, '( T2,"EWALD| ",A,A18,A,T71,F10.4 )') &
     358         1423 :                'Real Space Cutoff [', 'ANGSTROM', ']', dummy
     359              : 
     360         1874 :             SELECT CASE (ewald_env%ewald_type)
     361              :             CASE (do_ewald_ewald)
     362              :                WRITE (iw, '( T2,"EWALD| ",A,T51,3I10 )') &
     363          451 :                   'G-space max. Miller index', ewald_env%gmax
     364              :             CASE (do_ewald_pme)
     365              :                WRITE (iw, '( T2,"EWALD| ",A,T71,I10 )') &
     366           43 :                   'Max small-grid points (input) ', ewald_env%ns_max
     367              :                WRITE (iw, '( T2,"EWALD| ",A,T71,E10.4 )') &
     368           43 :                   'Gaussian tolerance (input) ', ewald_env%epsilon
     369              :             CASE (do_ewald_spme)
     370              :                WRITE (iw, '( T2,"EWALD| ",A,T51,3I10 )') &
     371          929 :                   'G-space max. Miller index', ewald_env%gmax
     372              :                WRITE (iw, '( T2,"EWALD| ",A,T71,I10 )') &
     373          929 :                   'Spline interpolation order ', ewald_env%o_spline
     374              :             CASE DEFAULT
     375         1423 :                CPABORT("")
     376              :             END SELECT
     377              :          ELSE
     378          485 :             WRITE (iw, '( T2,"EWALD| ",T73, A )') 'not used'
     379              :          END IF
     380         1908 :          CALL section_release(section)
     381              :       END IF
     382              :       CALL cp_print_key_finished_output(iw, logger, ewald_section, &
     383         3839 :                                         "PRINT%PROGRAM_RUN_INFO")
     384              : 
     385         3839 :    END SUBROUTINE read_ewald_section
     386              : 
     387              : ! **************************************************************************************************
     388              : !> \brief Purpose: read the EWALD section for TB methods
     389              : !> \param ewald_env the pointer to the ewald_env
     390              : !> \param ewald_section ...
     391              : !> \param hmat ...
     392              : !> \param silent ...
     393              : !> \param pset ...
     394              : !> \param cell_periodic ...
     395              : !> \author JGH
     396              : ! **************************************************************************************************
     397         3374 :    SUBROUTINE read_ewald_section_tb(ewald_env, ewald_section, hmat, silent, pset, cell_periodic)
     398              :       TYPE(ewald_environment_type), INTENT(INOUT)        :: ewald_env
     399              :       TYPE(section_vals_type), POINTER                   :: ewald_section
     400              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: hmat
     401              :       LOGICAL, INTENT(IN), OPTIONAL                      :: silent
     402              :       CHARACTER(LEN=*), OPTIONAL                         :: pset
     403              :       INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL        :: cell_periodic
     404              : 
     405              :       CHARACTER(LEN=5)                                   :: param
     406              :       INTEGER                                            :: i, iw, n(3), poisson_key
     407              :       INTEGER, DIMENSION(3)                              :: poisson_periodic
     408          482 :       INTEGER, DIMENSION(:), POINTER                     :: gmax_read
     409              :       LOGICAL                                            :: do_print, explicit
     410              :       REAL(KIND=dp)                                      :: alat, cutoff, dummy, omega
     411              :       TYPE(cp_logger_type), POINTER                      :: logger
     412              :       TYPE(section_vals_type), POINTER                   :: poisson_section
     413              : 
     414          964 :       logger => cp_get_default_logger()
     415          482 :       do_print = .TRUE.
     416          482 :       IF (PRESENT(silent)) do_print = .NOT. silent
     417          482 :       param = "none"
     418          482 :       IF (PRESENT(pset)) param = pset
     419              : 
     420          482 :       IF (PRESENT(cell_periodic)) THEN
     421          482 :          poisson_section => ewald_env%poisson_section
     422          482 :          IF (ASSOCIATED(poisson_section)) THEN
     423          482 :             CALL section_vals_val_get(poisson_section, "PERIODIC", i_val=poisson_key)
     424          482 :             CALL tb_decode_periodicity(poisson_key, poisson_periodic)
     425         1910 :             IF (ANY(cell_periodic /= poisson_periodic)) THEN
     426              :                CALL cp_warn(__LOCATION__, &
     427              :                             "The selected periodicities in SUBSYS/CELL and DFT/POISSON do not match. "// &
     428              :                             "The TB Ewald electrostatics will use DFT/POISSON/PERIODIC="// &
     429              :                             TRIM(tb_periodicity_label(poisson_periodic))// &
     430            6 :                             " while SUBSYS/CELL/PERIODIC="//TRIM(tb_periodicity_label(cell_periodic))//".")
     431              :             END IF
     432              :          END IF
     433              :       END IF
     434              : 
     435          482 :       ewald_env%do_multipoles = .FALSE.
     436          482 :       ewald_env%do_ipol = 0
     437          482 :       ewald_env%eps_pol = 1.e-12_dp
     438          482 :       ewald_env%max_multipole = 0
     439          482 :       ewald_env%max_ipol_iter = 0
     440          482 :       ewald_env%epsilon = 1.e-12_dp
     441          482 :       ewald_env%ns_max = HUGE(0)
     442              : 
     443          482 :       CALL section_vals_val_get(ewald_section, "EWALD_TYPE", explicit=explicit)
     444          482 :       IF (explicit) THEN
     445          196 :          CALL section_vals_val_get(ewald_section, "EWALD_TYPE", i_val=ewald_env%ewald_type)
     446          196 :          IF (ewald_env%ewald_type /= do_ewald_spme) THEN
     447            0 :             CPABORT("TB needs EWALD_TYPE SPME")
     448              :          END IF
     449              :       ELSE
     450          286 :          ewald_env%ewald_type = do_ewald_spme
     451              :       END IF
     452              : 
     453          482 :       CALL section_vals_val_get(ewald_section, "ALPHA", explicit=explicit)
     454          482 :       IF (explicit) THEN
     455          202 :          CALL section_vals_val_get(ewald_section, "ALPHA", r_val=ewald_env%alpha)
     456              :       ELSE
     457          194 :          SELECT CASE (param)
     458              :          CASE DEFAULT
     459          194 :             CALL section_vals_val_get(ewald_section, "ALPHA", r_val=ewald_env%alpha)
     460              :          CASE ("EEQ")
     461           86 :             omega = ABS(det_3x3(hmat))
     462          280 :             ewald_env%alpha = SQRT(twopi)/omega**(1./3.)
     463              :          END SELECT
     464              :       END IF
     465              : 
     466          482 :       CALL section_vals_val_get(ewald_section, "EWALD_ACCURACY", explicit=explicit)
     467          482 :       IF (explicit) THEN
     468            0 :          CALL section_vals_val_get(ewald_section, "EWALD_ACCURACY", r_val=ewald_env%precs)
     469              :       ELSE
     470          482 :          CALL section_vals_val_get(ewald_section, "EWALD_ACCURACY", r_val=ewald_env%precs)
     471              :       END IF
     472              : 
     473          482 :       CALL section_vals_val_get(ewald_section, "O_SPLINE", explicit=explicit)
     474          482 :       IF (explicit) THEN
     475          108 :          CALL section_vals_val_get(ewald_section, "O_SPLINE", i_val=ewald_env%o_spline)
     476              :       ELSE
     477          278 :          SELECT CASE (param)
     478              :          CASE DEFAULT
     479          278 :             ewald_env%o_spline = 6
     480              :          CASE ("EEQ")
     481          374 :             ewald_env%o_spline = 4
     482              :          END SELECT
     483              :       END IF
     484              : 
     485          482 :       CALL section_vals_val_get(ewald_section, "RCUT", explicit=explicit)
     486          482 :       IF (explicit) THEN
     487            0 :          CALL section_vals_val_get(ewald_section, "RCUT", r_val=ewald_env%rcut)
     488              :       ELSE
     489          482 :          ewald_env%rcut = find_ewald_optimal_value(ewald_env%precs)/ewald_env%alpha
     490              :       END IF
     491              : 
     492          482 :       CALL section_vals_val_get(ewald_section, "GMAX", explicit=explicit)
     493          482 :       IF (explicit) THEN
     494          186 :          CALL section_vals_val_get(ewald_section, "GMAX", i_vals=gmax_read)
     495          314 :          SELECT CASE (SIZE(gmax_read, 1))
     496              :          CASE (1)
     497          512 :             ewald_env%gmax = gmax_read(1)
     498              :          CASE (3)
     499          232 :             ewald_env%gmax = gmax_read
     500              :          CASE DEFAULT
     501          186 :             CPABORT("")
     502              :          END SELECT
     503              :       ELSE
     504          210 :          SELECT CASE (param)
     505              :          CASE DEFAULT
     506              :             ! set GMAX using ECUT=alpha*45 Ry
     507          210 :             cutoff = 45._dp*ewald_env%alpha
     508              :          CASE ("EEQ")
     509              :             ! set GMAX using ECUT=alpha*45 Ry
     510          296 :             cutoff = 30._dp*ewald_env%alpha
     511              :          END SELECT
     512         1184 :          DO i = 1, 3
     513         3552 :             alat = SUM(hmat(:, i)**2)
     514          888 :             CPASSERT(alat /= 0._dp)
     515         1184 :             ewald_env%gmax(i) = 2*FLOOR(SQRT(2.0_dp*cutoff*alat)/twopi) + 1
     516              :          END DO
     517              :       END IF
     518         1928 :       n = ewald_env%gmax
     519         1928 :       ewald_env%gmax = pw_grid_n_for_fft(n, odd=.TRUE.)
     520              : 
     521              :       iw = cp_print_key_unit_nr(logger, ewald_section, "PRINT%PROGRAM_RUN_INFO", &
     522          482 :                                 extension=".log")
     523          482 :       IF (iw > 0 .AND. do_print) THEN
     524          213 :          WRITE (iw, '(/,T2,"EWALD| ",A,T67,A14 )') 'Summation is done by:', ADJUSTR("SPME")
     525          213 :          dummy = cp_unit_from_cp2k(ewald_env%alpha, "angstrom^-1")
     526              :          WRITE (iw, '( T2,"EWALD| ",A,A18,A,T71,F10.4 )') &
     527          213 :             'Alpha parameter [', 'ANGSTROM^-1', ']', dummy
     528          213 :          dummy = cp_unit_from_cp2k(ewald_env%rcut, "angstrom")
     529              :          WRITE (iw, '( T2,"EWALD| ",A,A18,A,T71,F10.4 )') &
     530          213 :             'Real Space Cutoff [', 'ANGSTROM', ']', dummy
     531              :          WRITE (iw, '( T2,"EWALD| ",A,T51,3I10 )') &
     532          213 :             'G-space max. Miller index', ewald_env%gmax
     533              :          WRITE (iw, '( T2,"EWALD| ",A,T71,I10 )') &
     534          213 :             'Spline interpolation order ', ewald_env%o_spline
     535              :       END IF
     536              :       CALL cp_print_key_finished_output(iw, logger, ewald_section, &
     537          482 :                                         "PRINT%PROGRAM_RUN_INFO")
     538              : 
     539          482 :    END SUBROUTINE read_ewald_section_tb
     540              : 
     541              : ! **************************************************************************************************
     542              : !> \brief Decode CP2K PERIODIC enum into the 3-component periodicity mask.
     543              : !> \param periodic_key input enum value
     544              : !> \param periodic periodicity mask
     545              : ! **************************************************************************************************
     546          482 :    SUBROUTINE tb_decode_periodicity(periodic_key, periodic)
     547              :       INTEGER, INTENT(IN)                                :: periodic_key
     548              :       INTEGER, DIMENSION(3), INTENT(OUT)                 :: periodic
     549              : 
     550          482 :       SELECT CASE (periodic_key)
     551              :       CASE (use_perd_x)
     552            0 :          periodic = [1, 0, 0]
     553              :       CASE (use_perd_y)
     554            0 :          periodic = [0, 1, 0]
     555              :       CASE (use_perd_z)
     556            0 :          periodic = [0, 0, 1]
     557              :       CASE (use_perd_xy)
     558            0 :          periodic = [1, 1, 0]
     559              :       CASE (use_perd_xz)
     560            0 :          periodic = [1, 0, 1]
     561              :       CASE (use_perd_yz)
     562            0 :          periodic = [0, 1, 1]
     563              :       CASE (use_perd_xyz)
     564          476 :          periodic = [1, 1, 1]
     565              :       CASE (use_perd_none)
     566            6 :          periodic = [0, 0, 0]
     567              :       CASE DEFAULT
     568          482 :          CPABORT("Invalid PERIODIC setting for TB Ewald")
     569              :       END SELECT
     570              : 
     571          482 :    END SUBROUTINE tb_decode_periodicity
     572              : 
     573              : ! **************************************************************************************************
     574              : !> \brief Return a compact label for a 3-component periodicity mask.
     575              : !> \param periodic periodicity mask
     576              : !> \return label
     577              : ! **************************************************************************************************
     578           12 :    FUNCTION tb_periodicity_label(periodic) RESULT(label)
     579              :       INTEGER, DIMENSION(3), INTENT(IN)                  :: periodic
     580              :       CHARACTER(LEN=4)                                   :: label
     581              : 
     582           12 :       label = ""
     583           30 :       IF (ALL(periodic == 0)) THEN
     584            6 :          label = "NONE"
     585              :       ELSE
     586            6 :          IF (periodic(1) == 1) label = TRIM(label)//"X"
     587            6 :          IF (periodic(2) == 1) label = TRIM(label)//"Y"
     588            6 :          IF (periodic(3) == 1) label = TRIM(label)//"Z"
     589              :       END IF
     590              : 
     591           12 :    END FUNCTION tb_periodicity_label
     592              : 
     593              : ! **************************************************************************************************
     594              : !> \brief triggers (by bisection) the optimal value for EWALD parameter x
     595              : !>      EXP(-x^2)/x^2 = EWALD_ACCURACY
     596              : !> \param precs ...
     597              : !> \return ...
     598              : !> \author Teodoro Laino [tlaino] - University of Zurich - 12.2007
     599              : ! **************************************************************************************************
     600         3267 :    FUNCTION find_ewald_optimal_value(precs) RESULT(value)
     601              :       REAL(KIND=dp)                                      :: precs, value
     602              : 
     603              :       REAL(KIND=dp)                                      :: func, func1, func2, s, s1, s2
     604              : 
     605         3267 :       s = 0.1_dp
     606         3267 :       func = EXP(-s**2)/s**2 - precs
     607         3267 :       CPASSERT(func > 0.0_dp)
     608       107323 :       DO WHILE (func > 0.0_dp)
     609       104056 :          s = s + 0.1_dp
     610       107323 :          func = EXP(-s**2)/s**2 - precs
     611              :       END DO
     612         3267 :       s2 = s
     613         3267 :       s1 = s - 0.1_dp
     614              :       ! Start bisection
     615              :       DO WHILE (.TRUE.)
     616        81649 :          func2 = EXP(-s2**2)/s2**2 - precs
     617        81649 :          func1 = EXP(-s1**2)/s1**2 - precs
     618        81649 :          CPASSERT(func1 >= 0)
     619        81649 :          CPASSERT(func2 <= 0)
     620        81649 :          s = 0.5_dp*(s1 + s2)
     621        81649 :          func = EXP(-s**2)/s**2 - precs
     622        81649 :          IF (func > 0.0_dp) THEN
     623              :             s1 = s
     624        29598 :          ELSE IF (func < 0.0_dp) THEN
     625        29598 :             s2 = s
     626              :          END IF
     627        81649 :          IF (ABS(func) < 100.0_dp*EPSILON(0.0_dp)) EXIT
     628              :       END DO
     629         3267 :       value = s
     630         3267 :    END FUNCTION find_ewald_optimal_value
     631              : 
     632            0 : END MODULE ewald_environment_types
        

Generated by: LCOV version 2.0-1