LCOV - code coverage report
Current view: top level - src - ewald_environment_types.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:34ef472) Lines: 188 191 98.4 %
Date: 2024-04-26 08:30:29 Functions: 7 8 87.5 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 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 cp_log_handling,                 ONLY: cp_get_default_logger,&
      16             :                                               cp_logger_type
      17             :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      18             :                                               cp_print_key_unit_nr
      19             :    USE cp_units,                        ONLY: cp_unit_from_cp2k
      20             :    USE input_cp2k_poisson,              ONLY: create_ewald_section
      21             :    USE input_enumeration_types,         ONLY: enum_i2c,&
      22             :                                               enumeration_type
      23             :    USE input_keyword_types,             ONLY: keyword_get,&
      24             :                                               keyword_type
      25             :    USE input_section_types,             ONLY: section_get_keyword,&
      26             :                                               section_release,&
      27             :                                               section_type,&
      28             :                                               section_vals_get_subs_vals,&
      29             :                                               section_vals_release,&
      30             :                                               section_vals_retain,&
      31             :                                               section_vals_type,&
      32             :                                               section_vals_val_get
      33             :    USE kinds,                           ONLY: dp
      34             :    USE mathconstants,                   ONLY: twopi
      35             :    USE message_passing,                 ONLY: mp_comm_type,&
      36             :                                               mp_para_env_release,&
      37             :                                               mp_para_env_type
      38             :    USE pw_grid_info,                    ONLY: pw_grid_n_for_fft
      39             :    USE pw_poisson_types,                ONLY: do_ewald_ewald,&
      40             :                                               do_ewald_none,&
      41             :                                               do_ewald_pme,&
      42             :                                               do_ewald_spme
      43             : #include "./base/base_uses.f90"
      44             : 
      45             :    IMPLICIT NONE
      46             :    PRIVATE
      47             : 
      48             : ! **************************************************************************************************
      49             : !> \brief to build arrays of pointers
      50             : !> \param ewald_env the pointer to the ewald_env
      51             : !> \par History
      52             : !>      11/03
      53             : !> \author CJM
      54             : ! **************************************************************************************************
      55             :    TYPE ewald_environment_type
      56             :       PRIVATE
      57             :       LOGICAL   :: do_multipoles ! Flag for using the multipole code
      58             :       INTEGER   :: do_ipol ! Solver for induced dipoles
      59             :       INTEGER   :: max_multipole ! max expansion in the multipoles
      60             :       INTEGER   :: max_ipol_iter ! max number of interaction for induced dipoles
      61             :       INTEGER   :: ewald_type ! type of ewald
      62             :       INTEGER   :: gmax(3) ! max Miller index
      63             :       INTEGER   :: ns_max ! # grid points for small grid (PME)
      64             :       INTEGER   :: o_spline ! order of spline (SPME)
      65             :       REAL(KIND=dp) :: precs ! precision achieved when evaluating the real-space part
      66             :       REAL(KIND=dp) :: alpha, rcut ! ewald alpha and real-space cutoff
      67             :       REAL(KIND=dp) :: epsilon ! tolerance for small grid (PME)
      68             :       REAL(KIND=dp) :: eps_pol ! tolerance for convergence of induced dipoles
      69             :       TYPE(mp_para_env_type), POINTER          :: para_env
      70             :       TYPE(section_vals_type), POINTER         :: poisson_section
      71             :       ! interaction cutoff is required to make the electrostatic interaction
      72             :       ! continuous at a pair distance equal to rcut. this is ignored by the
      73             :       ! multipole code and is otherwise only active when SHIFT_CUTOFF is used.
      74             :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: interaction_cutoffs
      75             :       ! store current cell, used to rebuild lazily.
      76             :       REAL(KIND=dp), DIMENSION(3, 3)          :: cell_hmat = -1.0_dp
      77             :    END TYPE ewald_environment_type
      78             : 
      79             : ! *** Public data types ***
      80             :    PUBLIC :: ewald_environment_type
      81             : 
      82             : ! *** Public subroutines ***
      83             :    PUBLIC :: ewald_env_get, &
      84             :              ewald_env_set, &
      85             :              ewald_env_create, &
      86             :              ewald_env_release, &
      87             :              read_ewald_section, &
      88             :              read_ewald_section_tb
      89             : 
      90             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ewald_environment_types'
      91             : 
      92             : CONTAINS
      93             : 
      94             : ! **************************************************************************************************
      95             : !> \brief Purpose: Get the EWALD environment.
      96             : !> \param ewald_env the pointer to the ewald_env
      97             : !> \param ewald_type ...
      98             : !> \param alpha ...
      99             : !> \param eps_pol ...
     100             : !> \param epsilon ...
     101             : !> \param gmax ...
     102             : !> \param ns_max ...
     103             : !> \param o_spline ...
     104             : !> \param group ...
     105             : !> \param para_env ...
     106             : !> \param poisson_section ...
     107             : !> \param precs ...
     108             : !> \param rcut ...
     109             : !> \param do_multipoles ...
     110             : !> \param max_multipole ...
     111             : !> \param do_ipol ...
     112             : !> \param max_ipol_iter ...
     113             : !> \param interaction_cutoffs ...
     114             : !> \param cell_hmat ...
     115             : !> \par History
     116             : !>      11/03
     117             : !> \author CJM
     118             : ! **************************************************************************************************
     119      513105 :    SUBROUTINE ewald_env_get(ewald_env, ewald_type, alpha, eps_pol, epsilon, &
     120             :                             gmax, ns_max, o_spline, group, para_env, poisson_section, precs, &
     121             :                             rcut, do_multipoles, max_multipole, do_ipol, max_ipol_iter, &
     122             :                             interaction_cutoffs, cell_hmat)
     123             :       TYPE(ewald_environment_type), INTENT(IN)           :: ewald_env
     124             :       INTEGER, OPTIONAL                                  :: ewald_type
     125             :       REAL(KIND=dp), OPTIONAL                            :: alpha, eps_pol, epsilon
     126             :       INTEGER, OPTIONAL                                  :: gmax(3), ns_max, o_spline
     127             :       TYPE(mp_comm_type), INTENT(OUT), OPTIONAL          :: group
     128             :       TYPE(mp_para_env_type), OPTIONAL, POINTER          :: para_env
     129             :       TYPE(section_vals_type), OPTIONAL, POINTER         :: poisson_section
     130             :       REAL(KIND=dp), OPTIONAL                            :: precs, rcut
     131             :       LOGICAL, INTENT(OUT), OPTIONAL                     :: do_multipoles
     132             :       INTEGER, INTENT(OUT), OPTIONAL                     :: max_multipole, do_ipol, max_ipol_iter
     133             :       REAL(KIND=dp), DIMENSION(:, :, :), OPTIONAL, &
     134             :          POINTER                                         :: interaction_cutoffs
     135             :       REAL(KIND=dp), DIMENSION(3, 3), OPTIONAL           :: cell_hmat
     136             : 
     137      513105 :       IF (PRESENT(ewald_type)) ewald_type = ewald_env%ewald_type
     138      513105 :       IF (PRESENT(do_multipoles)) do_multipoles = ewald_env%do_multipoles
     139      513105 :       IF (PRESENT(do_ipol)) do_ipol = ewald_env%do_ipol
     140      513105 :       IF (PRESENT(max_multipole)) max_multipole = ewald_env%max_multipole
     141      513105 :       IF (PRESENT(max_ipol_iter)) max_ipol_iter = ewald_env%max_ipol_iter
     142      513105 :       IF (PRESENT(alpha)) alpha = ewald_env%alpha
     143      513105 :       IF (PRESENT(precs)) precs = ewald_env%precs
     144      513105 :       IF (PRESENT(rcut)) rcut = ewald_env%rcut
     145      513105 :       IF (PRESENT(epsilon)) epsilon = ewald_env%epsilon
     146      513105 :       IF (PRESENT(eps_pol)) eps_pol = ewald_env%eps_pol
     147      529813 :       IF (PRESENT(gmax)) gmax = ewald_env%gmax
     148      513105 :       IF (PRESENT(ns_max)) ns_max = ewald_env%ns_max
     149      513105 :       IF (PRESENT(o_spline)) o_spline = ewald_env%o_spline
     150      513105 :       IF (PRESENT(group)) group = ewald_env%para_env
     151      513105 :       IF (PRESENT(para_env)) para_env => ewald_env%para_env
     152      513105 :       IF (PRESENT(poisson_section)) poisson_section => ewald_env%poisson_section
     153      513105 :       IF (PRESENT(interaction_cutoffs)) interaction_cutoffs => &
     154       83143 :          ewald_env%interaction_cutoffs
     155     1641089 :       IF (PRESENT(cell_hmat)) cell_hmat = ewald_env%cell_hmat
     156      513105 :    END SUBROUTINE ewald_env_get
     157             : 
     158             : ! **************************************************************************************************
     159             : !> \brief Purpose: Set the EWALD environment.
     160             : !> \param ewald_env the pointer to the ewald_env
     161             : !> \param ewald_type ...
     162             : !> \param alpha ...
     163             : !> \param epsilon ...
     164             : !> \param eps_pol ...
     165             : !> \param gmax ...
     166             : !> \param ns_max ...
     167             : !> \param precs ...
     168             : !> \param o_spline ...
     169             : !> \param para_env ...
     170             : !> \param poisson_section ...
     171             : !> \param interaction_cutoffs ...
     172             : !> \param cell_hmat ...
     173             : !> \par History
     174             : !>      11/03
     175             : !> \author CJM
     176             : ! **************************************************************************************************
     177       22514 :    SUBROUTINE ewald_env_set(ewald_env, ewald_type, alpha, epsilon, eps_pol, &
     178             :                             gmax, ns_max, precs, o_spline, para_env, poisson_section, &
     179             :                             interaction_cutoffs, cell_hmat)
     180             : 
     181             :       TYPE(ewald_environment_type), INTENT(INOUT)        :: ewald_env
     182             :       INTEGER, OPTIONAL                                  :: ewald_type
     183             :       REAL(KIND=dp), OPTIONAL                            :: alpha, epsilon, eps_pol
     184             :       INTEGER, OPTIONAL                                  :: gmax(3), ns_max
     185             :       REAL(KIND=dp), OPTIONAL                            :: precs
     186             :       INTEGER, OPTIONAL                                  :: o_spline
     187             :       TYPE(mp_para_env_type), OPTIONAL, POINTER          :: para_env
     188             :       TYPE(section_vals_type), OPTIONAL, POINTER         :: poisson_section
     189             :       REAL(KIND=dp), DIMENSION(:, :, :), OPTIONAL, &
     190             :          POINTER                                         :: interaction_cutoffs
     191             :       REAL(KIND=dp), DIMENSION(3, 3), OPTIONAL           :: cell_hmat
     192             : 
     193       22514 :       IF (PRESENT(ewald_type)) ewald_env%ewald_type = ewald_type
     194       22514 :       IF (PRESENT(alpha)) ewald_env%alpha = alpha
     195       22514 :       IF (PRESENT(precs)) ewald_env%precs = precs
     196       22514 :       IF (PRESENT(epsilon)) ewald_env%epsilon = epsilon
     197       22514 :       IF (PRESENT(eps_pol)) ewald_env%eps_pol = eps_pol
     198       22514 :       IF (PRESENT(gmax)) ewald_env%gmax = gmax
     199       22514 :       IF (PRESENT(ns_max)) ewald_env%ns_max = ns_max
     200       22514 :       IF (PRESENT(o_spline)) ewald_env%o_spline = o_spline
     201       22514 :       IF (PRESENT(para_env)) ewald_env%para_env => para_env
     202       22514 :       IF (PRESENT(poisson_section)) THEN
     203        4169 :          CALL section_vals_retain(poisson_section)
     204        4169 :          CALL section_vals_release(ewald_env%poisson_section)
     205        4169 :          ewald_env%poisson_section => poisson_section
     206             :       END IF
     207       22514 :       IF (PRESENT(interaction_cutoffs)) ewald_env%interaction_cutoffs => &
     208        2639 :          interaction_cutoffs
     209      226692 :       IF (PRESENT(cell_hmat)) ewald_env%cell_hmat = cell_hmat
     210       22514 :    END SUBROUTINE ewald_env_set
     211             : 
     212             : ! **************************************************************************************************
     213             : !> \brief allocates and intitializes a ewald_env
     214             : !> \param ewald_env the object to create
     215             : !> \param para_env ...
     216             : !> \par History
     217             : !>      12.2002 created [fawzi]
     218             : !> \author Fawzi Mohamed
     219             : ! **************************************************************************************************
     220       54197 :    SUBROUTINE ewald_env_create(ewald_env, para_env)
     221             :       TYPE(ewald_environment_type), INTENT(OUT)          :: ewald_env
     222             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     223             : 
     224        4169 :       NULLIFY (ewald_env%poisson_section)
     225        4169 :       CALL para_env%retain()
     226        4169 :       ewald_env%para_env => para_env
     227        4169 :       NULLIFY (ewald_env%interaction_cutoffs) ! allocated and initialized later
     228        4169 :    END SUBROUTINE ewald_env_create
     229             : 
     230             : ! **************************************************************************************************
     231             : !> \brief releases the given ewald_env (see doc/ReferenceCounting.html)
     232             : !> \param ewald_env the object to release
     233             : !> \par History
     234             : !>      12.2002 created [fawzi]
     235             : !> \author Fawzi Mohamed
     236             : ! **************************************************************************************************
     237        4169 :    SUBROUTINE ewald_env_release(ewald_env)
     238             :       TYPE(ewald_environment_type), INTENT(INOUT)        :: ewald_env
     239             : 
     240        4169 :       CALL mp_para_env_release(ewald_env%para_env)
     241        4169 :       CALL section_vals_release(ewald_env%poisson_section)
     242        4169 :       IF (ASSOCIATED(ewald_env%interaction_cutoffs)) THEN
     243        2639 :          DEALLOCATE (ewald_env%interaction_cutoffs)
     244             :       END IF
     245             : 
     246        4169 :    END SUBROUTINE ewald_env_release
     247             : 
     248             : ! **************************************************************************************************
     249             : !> \brief Purpose: read the EWALD section
     250             : !> \param ewald_env the pointer to the ewald_env
     251             : !> \param ewald_section ...
     252             : !> \author Teodoro Laino [tlaino] -University of Zurich - 2005
     253             : ! **************************************************************************************************
     254        3831 :    SUBROUTINE read_ewald_section(ewald_env, ewald_section)
     255             :       TYPE(ewald_environment_type), INTENT(INOUT)        :: ewald_env
     256             :       TYPE(section_vals_type), POINTER                   :: ewald_section
     257             : 
     258             :       INTEGER                                            :: iw
     259        3831 :       INTEGER, DIMENSION(:), POINTER                     :: gmax_read
     260             :       LOGICAL                                            :: explicit
     261             :       REAL(KIND=dp)                                      :: dummy
     262             :       TYPE(cp_logger_type), POINTER                      :: logger
     263             :       TYPE(enumeration_type), POINTER                    :: enum
     264             :       TYPE(keyword_type), POINTER                        :: keyword
     265             :       TYPE(section_type), POINTER                        :: section
     266             :       TYPE(section_vals_type), POINTER                   :: multipole_section
     267             : 
     268        3831 :       NULLIFY (enum, keyword, section, multipole_section)
     269        7662 :       logger => cp_get_default_logger()
     270        3831 :       CALL section_vals_val_get(ewald_section, "EWALD_TYPE", i_val=ewald_env%ewald_type)
     271        3831 :       CALL section_vals_val_get(ewald_section, "ALPHA", r_val=ewald_env%alpha)
     272        3831 :       CALL section_vals_val_get(ewald_section, "EWALD_ACCURACY", r_val=ewald_env%precs)
     273             : 
     274        3831 :       IF (ewald_env%ewald_type == do_ewald_none) THEN
     275        1046 :          ewald_env%rcut = 0.0_dp
     276             :       ELSE
     277        2785 :          CALL section_vals_val_get(ewald_section, "RCUT", explicit=explicit)
     278        2785 :          IF (explicit) THEN
     279          10 :             CALL section_vals_val_get(ewald_section, "RCUT", r_val=ewald_env%rcut)
     280             :          ELSE
     281        2775 :             ewald_env%rcut = find_ewald_optimal_value(ewald_env%precs)/ewald_env%alpha
     282             :          END IF
     283             :       END IF
     284             :       ! we have no defaults for gmax, gmax is only needed for ewald and spme
     285        6530 :       SELECT CASE (ewald_env%ewald_type)
     286             :       CASE (do_ewald_ewald, do_ewald_spme)
     287        2699 :          CALL section_vals_val_get(ewald_section, "GMAX", i_vals=gmax_read)
     288        5088 :          SELECT CASE (SIZE(gmax_read, 1))
     289             :          CASE (1)
     290        9556 :             ewald_env%gmax = gmax_read(1)
     291             :          CASE (3)
     292        1240 :             ewald_env%gmax = gmax_read
     293             :          CASE DEFAULT
     294        2699 :             CPABORT("")
     295             :          END SELECT
     296        2699 :          IF (ewald_env%ewald_type == do_ewald_spme) THEN
     297        1878 :             CALL section_vals_val_get(ewald_section, "O_SPLINE", i_val=ewald_env%o_spline)
     298             :          END IF
     299             :       CASE (do_ewald_pme)
     300          86 :          CALL section_vals_val_get(ewald_section, "NS_MAX", i_val=ewald_env%ns_max)
     301          86 :          CALL section_vals_val_get(ewald_section, "EPSILON", r_val=ewald_env%epsilon)
     302             :       CASE DEFAULT
     303             :          ! this should not be used for do_ewald_none
     304        4184 :          ewald_env%gmax = HUGE(0)
     305        4877 :          ewald_env%ns_max = HUGE(0)
     306             :       END SELECT
     307             : 
     308             :       ! Multipoles
     309        3831 :       multipole_section => section_vals_get_subs_vals(ewald_section, "MULTIPOLES")
     310        3831 :       CALL section_vals_val_get(multipole_section, "_SECTION_PARAMETERS_", l_val=ewald_env%do_multipoles)
     311        3831 :       CALL section_vals_val_get(multipole_section, "POL_SCF", i_val=ewald_env%do_ipol)
     312        3831 :       CALL section_vals_val_get(multipole_section, "EPS_POL", r_val=ewald_env%eps_pol)
     313        3831 :       IF (ewald_env%do_multipoles) THEN
     314         336 :          SELECT CASE (ewald_env%ewald_type)
     315             :          CASE (do_ewald_ewald)
     316             :             CALL section_vals_val_get(multipole_section, "MAX_MULTIPOLE_EXPANSION", &
     317         168 :                                       i_val=ewald_env%max_multipole)
     318         168 :             CALL section_vals_val_get(multipole_section, "MAX_IPOL_ITER", i_val=ewald_env%max_ipol_iter)
     319             :          CASE DEFAULT
     320         168 :             CPABORT("Multipole code works at the moment only with standard EWALD sums.")
     321             :          END SELECT
     322             :       END IF
     323             : 
     324             :       iw = cp_print_key_unit_nr(logger, ewald_section, "PRINT%PROGRAM_RUN_INFO", &
     325        3831 :                                 extension=".log")
     326        3831 :       IF (iw > 0) THEN
     327        1904 :          NULLIFY (keyword, enum)
     328        1904 :          CALL create_ewald_section(section)
     329        1904 :          IF (ewald_env%ewald_type /= do_ewald_none) THEN
     330        1419 :             keyword => section_get_keyword(section, "EWALD_TYPE")
     331        1419 :             CALL keyword_get(keyword, enum=enum)
     332        1419 :             WRITE (iw, '(/,T2,"EWALD| ",A,T67,A14 )') 'Summation is done by:', &
     333        2838 :                ADJUSTR(TRIM(enum_i2c(enum, ewald_env%ewald_type)))
     334        1419 :             IF (ewald_env%do_multipoles) THEN
     335          84 :                NULLIFY (keyword, enum)
     336          84 :                keyword => section_get_keyword(section, "MULTIPOLES%MAX_MULTIPOLE_EXPANSION")
     337          84 :                CALL keyword_get(keyword, enum=enum)
     338          84 :                WRITE (iw, '( T2,"EWALD| ",A )') 'Enabled Multipole Method'
     339          84 :                WRITE (iw, '( T2,"EWALD| ",A,T67,A14 )') 'Max Term in Multipole Expansion :', &
     340         168 :                   ADJUSTR(TRIM(enum_i2c(enum, ewald_env%max_multipole)))
     341          84 :                WRITE (iw, '( T2,"EWALD| ",A,T67,3I10 )') 'Max number Iterations for IPOL :', &
     342         168 :                   ewald_env%max_ipol_iter
     343             :             END IF
     344        1419 :             dummy = cp_unit_from_cp2k(ewald_env%alpha, "angstrom^-1")
     345             :             WRITE (iw, '( T2,"EWALD| ",A,A18,A,T71,F10.4 )') &
     346        1419 :                'Alpha parameter [', 'ANGSTROM^-1', ']', dummy
     347        1419 :             dummy = cp_unit_from_cp2k(ewald_env%rcut, "angstrom")
     348             :             WRITE (iw, '( T2,"EWALD| ",A,A18,A,T71,F10.4 )') &
     349        1419 :                'Real Space Cutoff [', 'ANGSTROM', ']', dummy
     350             : 
     351        1869 :             SELECT CASE (ewald_env%ewald_type)
     352             :             CASE (do_ewald_ewald)
     353             :                WRITE (iw, '( T2,"EWALD| ",A,T51,3I10 )') &
     354         450 :                   'G-space max. Miller index', ewald_env%gmax
     355             :             CASE (do_ewald_pme)
     356             :                WRITE (iw, '( T2,"EWALD| ",A,T71,I10 )') &
     357          43 :                   'Max small-grid points (input) ', ewald_env%ns_max
     358             :                WRITE (iw, '( T2,"EWALD| ",A,T71,E10.4 )') &
     359          43 :                   'Gaussian tolerance (input) ', ewald_env%epsilon
     360             :             CASE (do_ewald_spme)
     361             :                WRITE (iw, '( T2,"EWALD| ",A,T51,3I10 )') &
     362         926 :                   'G-space max. Miller index', ewald_env%gmax
     363             :                WRITE (iw, '( T2,"EWALD| ",A,T71,I10 )') &
     364         926 :                   'Spline interpolation order ', ewald_env%o_spline
     365             :             CASE DEFAULT
     366        1419 :                CPABORT("")
     367             :             END SELECT
     368             :          ELSE
     369         485 :             WRITE (iw, '( T2,"EWALD| ",T73, A )') 'not used'
     370             :          END IF
     371        1904 :          CALL section_release(section)
     372             :       END IF
     373             :       CALL cp_print_key_finished_output(iw, logger, ewald_section, &
     374        3831 :                                         "PRINT%PROGRAM_RUN_INFO")
     375             : 
     376        3831 :    END SUBROUTINE read_ewald_section
     377             : 
     378             : ! **************************************************************************************************
     379             : !> \brief Purpose: read the EWALD section for TB methods
     380             : !> \param ewald_env the pointer to the ewald_env
     381             : !> \param ewald_section ...
     382             : !> \param hmat ...
     383             : !> \author JGH
     384             : ! **************************************************************************************************
     385        1690 :    SUBROUTINE read_ewald_section_tb(ewald_env, ewald_section, hmat)
     386             :       TYPE(ewald_environment_type), INTENT(INOUT)        :: ewald_env
     387             :       TYPE(section_vals_type), POINTER                   :: ewald_section
     388             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: hmat
     389             : 
     390             :       INTEGER                                            :: i, iw, n(3)
     391         338 :       INTEGER, DIMENSION(:), POINTER                     :: gmax_read
     392             :       LOGICAL                                            :: explicit
     393             :       REAL(KIND=dp)                                      :: alat, cutoff, dummy
     394             :       TYPE(cp_logger_type), POINTER                      :: logger
     395             : 
     396         676 :       logger => cp_get_default_logger()
     397             : 
     398         338 :       ewald_env%do_multipoles = .FALSE.
     399         338 :       ewald_env%do_ipol = 0
     400         338 :       ewald_env%eps_pol = 1.e-12_dp
     401         338 :       ewald_env%max_multipole = 0
     402         338 :       ewald_env%max_ipol_iter = 0
     403         338 :       ewald_env%epsilon = 1.e-12_dp
     404         338 :       ewald_env%ns_max = HUGE(0)
     405             : 
     406         338 :       CALL section_vals_val_get(ewald_section, "EWALD_TYPE", explicit=explicit)
     407         338 :       IF (explicit) THEN
     408         160 :          CALL section_vals_val_get(ewald_section, "EWALD_TYPE", i_val=ewald_env%ewald_type)
     409         160 :          IF (ewald_env%ewald_type /= do_ewald_spme) THEN
     410           0 :             CPABORT("TB needs EWALD_TYPE SPME")
     411             :          END IF
     412             :       ELSE
     413         178 :          ewald_env%ewald_type = do_ewald_spme
     414             :       END IF
     415             : 
     416         338 :       CALL section_vals_val_get(ewald_section, "ALPHA", explicit=explicit)
     417         338 :       IF (explicit) THEN
     418         158 :          CALL section_vals_val_get(ewald_section, "ALPHA", r_val=ewald_env%alpha)
     419             :       ELSE
     420         180 :          ewald_env%alpha = 1.0_dp
     421             :       END IF
     422             : 
     423         338 :       CALL section_vals_val_get(ewald_section, "EWALD_ACCURACY", r_val=ewald_env%precs)
     424         338 :       CALL section_vals_val_get(ewald_section, "O_SPLINE", i_val=ewald_env%o_spline)
     425             : 
     426         338 :       CALL section_vals_val_get(ewald_section, "RCUT", explicit=explicit)
     427         338 :       IF (explicit) THEN
     428           0 :          CALL section_vals_val_get(ewald_section, "RCUT", r_val=ewald_env%rcut)
     429             :       ELSE
     430         338 :          ewald_env%rcut = find_ewald_optimal_value(ewald_env%precs)/ewald_env%alpha
     431             :       END IF
     432             : 
     433         338 :       CALL section_vals_val_get(ewald_section, "GMAX", explicit=explicit)
     434         338 :       IF (explicit) THEN
     435         156 :          CALL section_vals_val_get(ewald_section, "GMAX", i_vals=gmax_read)
     436         254 :          SELECT CASE (SIZE(gmax_read, 1))
     437             :          CASE (1)
     438         392 :             ewald_env%gmax = gmax_read(1)
     439             :          CASE (3)
     440         232 :             ewald_env%gmax = gmax_read
     441             :          CASE DEFAULT
     442         156 :             CPABORT("")
     443             :          END SELECT
     444             :       ELSE
     445             :          ! set GMAX using ECUT=alpha*45 Ry
     446         182 :          cutoff = 45._dp*ewald_env%alpha
     447         728 :          DO i = 1, 3
     448        2184 :             alat = SUM(hmat(:, i)**2)
     449         546 :             CPASSERT(alat /= 0._dp)
     450         728 :             ewald_env%gmax(i) = 2*FLOOR(SQRT(2.0_dp*cutoff*alat)/twopi) + 1
     451             :          END DO
     452             :       END IF
     453        1352 :       n = ewald_env%gmax
     454        1352 :       ewald_env%gmax = pw_grid_n_for_fft(n, odd=.TRUE.)
     455             : 
     456             :       iw = cp_print_key_unit_nr(logger, ewald_section, "PRINT%PROGRAM_RUN_INFO", &
     457         338 :                                 extension=".log")
     458         338 :       IF (iw > 0) THEN
     459         169 :          WRITE (iw, '(/,T2,"EWALD| ",A,T67,A14 )') 'Summation is done by:', ADJUSTR("SPME")
     460         169 :          dummy = cp_unit_from_cp2k(ewald_env%alpha, "angstrom^-1")
     461             :          WRITE (iw, '( T2,"EWALD| ",A,A18,A,T71,F10.4 )') &
     462         169 :             'Alpha parameter [', 'ANGSTROM^-1', ']', dummy
     463         169 :          dummy = cp_unit_from_cp2k(ewald_env%rcut, "angstrom")
     464             :          WRITE (iw, '( T2,"EWALD| ",A,A18,A,T71,F10.4 )') &
     465         169 :             'Real Space Cutoff [', 'ANGSTROM', ']', dummy
     466             :          WRITE (iw, '( T2,"EWALD| ",A,T51,3I10 )') &
     467         169 :             'G-space max. Miller index', ewald_env%gmax
     468             :          WRITE (iw, '( T2,"EWALD| ",A,T71,I10 )') &
     469         169 :             'Spline interpolation order ', ewald_env%o_spline
     470             :       END IF
     471             :       CALL cp_print_key_finished_output(iw, logger, ewald_section, &
     472         338 :                                         "PRINT%PROGRAM_RUN_INFO")
     473             : 
     474         338 :    END SUBROUTINE read_ewald_section_tb
     475             : 
     476             : ! **************************************************************************************************
     477             : !> \brief triggers (by bisection) the optimal value for EWALD parameter x
     478             : !>      EXP(-x^2)/x^2 = EWALD_ACCURACY
     479             : !> \param precs ...
     480             : !> \return ...
     481             : !> \author Teodoro Laino [tlaino] - University of Zurich - 12.2007
     482             : ! **************************************************************************************************
     483        3113 :    FUNCTION find_ewald_optimal_value(precs) RESULT(value)
     484             :       REAL(KIND=dp)                                      :: precs, value
     485             : 
     486             :       REAL(KIND=dp)                                      :: func, func1, func2, s, s1, s2
     487             : 
     488        3113 :       s = 0.1_dp
     489        3113 :       func = EXP(-s**2)/s**2 - precs
     490        3113 :       CPASSERT(func > 0.0_dp)
     491      102087 :       DO WHILE (func > 0.0_dp)
     492       98974 :          s = s + 0.1_dp
     493      102087 :          func = EXP(-s**2)/s**2 - precs
     494             :       END DO
     495        3113 :       s2 = s
     496        3113 :       s1 = s - 0.1_dp
     497             :       ! Start bisection
     498             :       DO WHILE (.TRUE.)
     499       77953 :          func2 = EXP(-s2**2)/s2**2 - precs
     500       77953 :          func1 = EXP(-s1**2)/s1**2 - precs
     501       77953 :          CPASSERT(func1 >= 0)
     502       77953 :          CPASSERT(func2 <= 0)
     503       77953 :          s = 0.5_dp*(s1 + s2)
     504       77953 :          func = EXP(-s**2)/s**2 - precs
     505       77953 :          IF (func > 0.0_dp) THEN
     506             :             s1 = s
     507       28366 :          ELSE IF (func < 0.0_dp) THEN
     508       28366 :             s2 = s
     509             :          END IF
     510       77953 :          IF (ABS(func) < 100.0_dp*EPSILON(0.0_dp)) EXIT
     511             :       END DO
     512        3113 :       value = s
     513        3113 :    END FUNCTION find_ewald_optimal_value
     514             : 
     515           0 : END MODULE ewald_environment_types
     516             : 

Generated by: LCOV version 1.15