32 #include "../base/base_uses.f90"
38 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .false.
40 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'eri_mme_types'
44 PUBLIC :: eri_mme_param, &
56 REAL(kind=
dp) :: cutoff = 0.0_dp
57 INTEGER :: n_minimax = 0
58 REAL(kind=
dp),
POINTER, &
59 DIMENSION(:) :: minimax_aw => null()
60 REAL(kind=
dp) :: error = 0.0_dp
64 INTEGER :: n_minimax = 0
65 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat = 0.0_dp, h_inv = 0.0_dp
66 REAL(kind=
dp) :: vol = 0.0_dp
67 LOGICAL :: is_ortho = .false.
68 REAL(kind=
dp) :: cutoff = 0.0_dp
69 LOGICAL :: do_calib_cutoff = .false.
70 LOGICAL :: do_error_est = .false.
71 LOGICAL :: print_calib = .false.
72 REAL(kind=
dp) :: cutoff_min = 0.0_dp, cutoff_max = 0.0_dp, cutoff_delta = 0.0_dp, &
74 REAL(kind=
dp) :: err_mm = 0.0_dp, err_c = 0.0_dp
75 REAL(kind=
dp) :: mm_delta = 0.0_dp
76 REAL(kind=
dp) :: g_min = 0.0_dp, r_min = 0.0_dp
77 LOGICAL :: is_valid = .false.
78 LOGICAL :: debug = .false.
79 REAL(kind=
dp) :: debug_delta = 0.0_dp
80 INTEGER :: debug_nsum = 0
81 REAL(kind=
dp) :: c_mm = 0.0_dp
82 INTEGER :: unit_nr = -1
83 REAL(kind=
dp) :: sum_precision = 0.0_dp
84 INTEGER :: n_grids = 0
85 TYPE(minimax_grid),
DIMENSION(:), &
86 ALLOCATABLE :: minimax_grid
87 REAL(kind=
dp) :: zet_max = 0.0_dp, zet_min = 0.0_dp
88 INTEGER :: l_mm = -1, l_max_zet = -1
89 INTEGER :: potential = 0
90 REAL(kind=
dp) :: pot_par = 0.0_dp
91 END TYPE eri_mme_param
113 SUBROUTINE eri_mme_init(param, n_minimax, cutoff, do_calib_cutoff, do_error_est, &
114 cutoff_min, cutoff_max, cutoff_eps, cutoff_delta, sum_precision, &
115 debug, debug_delta, debug_nsum, unit_nr, print_calib)
116 TYPE(eri_mme_param),
INTENT(OUT) :: param
117 INTEGER,
INTENT(IN) :: n_minimax
118 REAL(kind=
dp),
INTENT(IN) :: cutoff
119 LOGICAL,
INTENT(IN) :: do_calib_cutoff, do_error_est
120 REAL(kind=
dp),
INTENT(IN) :: cutoff_min, cutoff_max, cutoff_eps, &
121 cutoff_delta, sum_precision
122 LOGICAL,
INTENT(IN) :: debug
123 REAL(kind=
dp),
INTENT(IN) :: debug_delta
124 INTEGER,
INTENT(IN) :: debug_nsum, unit_nr
125 LOGICAL,
INTENT(IN) :: print_calib
127 CHARACTER(len=2) :: string
131 cpabort(
"The maximum allowed number of minimax points N_MINIMAX is "//trim(string))
133 param%n_minimax = n_minimax
135 param%cutoff = cutoff
136 param%do_calib_cutoff = do_calib_cutoff
137 param%do_error_est = do_error_est
138 param%cutoff_min = cutoff_min
139 param%cutoff_max = cutoff_max
140 param%cutoff_eps = cutoff_eps
141 param%cutoff_delta = cutoff_delta
142 param%sum_precision = sum_precision
144 param%debug_delta = debug_delta
145 param%debug_nsum = debug_nsum
146 param%print_calib = print_calib
147 param%unit_nr = unit_nr
148 param%err_mm = -1.0_dp
149 param%err_c = -1.0_dp
151 param%is_valid = .false.
152 ALLOCATE (param%minimax_grid(param%n_grids))
175 TYPE(eri_mme_param),
INTENT(INOUT) :: param
176 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: hmat
177 LOGICAL,
INTENT(IN) :: is_ortho
178 REAL(kind=
dp),
INTENT(IN) :: zet_min, zet_max
179 INTEGER,
INTENT(IN) :: l_max_zet, l_max
180 TYPE(mp_para_env_type),
INTENT(IN),
OPTIONAL :: para_env
181 INTEGER,
INTENT(IN),
OPTIONAL :: potential
182 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: pot_par
184 CHARACTER(LEN=*),
PARAMETER :: routinen =
'eri_mme_set_params'
186 INTEGER :: handle, l_mm, n_grids
188 REAL(kind=
dp) :: cutoff
189 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: minimax_aw
191 CALL timeset(routinen, handle)
194 s_only = l_max .EQ. 0
199 l_mm = merge(0, 1, s_only)
206 param%is_ortho = is_ortho
213 param%zet_max = zet_max
214 param%zet_min = zet_min
215 param%l_max_zet = l_max_zet
219 IF (.NOT. param%is_ortho)
THEN
220 param%do_calib_cutoff = .false.
221 param%do_error_est = .false.
224 n_grids = param%n_grids
229 IF (param%do_calib_cutoff)
THEN
231 zet_min, l_mm, zet_max, l_max_zet, param%n_minimax, &
232 param%cutoff_min, param%cutoff_max, param%cutoff_eps, &
233 param%cutoff_delta, cutoff, param%err_mm, param%err_c, &
234 param%C_mm, para_env, param%print_calib, param%unit_nr)
236 param%cutoff = cutoff
237 ELSE IF (param%do_error_est)
THEN
238 ALLOCATE (minimax_aw(2*param%n_minimax))
240 zet_min, l_mm, zet_max, l_max_zet, param%n_minimax, &
241 minimax_aw, param%err_mm, param%err_c, param%C_mm, para_env)
242 DEALLOCATE (minimax_aw)
245 param%is_valid = .true.
249 CALL timestop(handle)
262 TYPE(eri_mme_param),
INTENT(INOUT) :: param
263 INTEGER,
INTENT(IN),
OPTIONAL :: potential
264 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: pot_par
266 REAL(kind=
dp) :: cutoff_max, cutoff_min, cutoff_rel
267 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: minimax_aw
269 cpassert(param%is_valid)
271 IF (
PRESENT(potential))
THEN
272 param%potential = potential
277 IF (
PRESENT(pot_par))
THEN
278 param%pot_par = pot_par
280 param%pot_par = 0.0_dp
283 ALLOCATE (minimax_aw(2*param%n_minimax))
285 CALL minimax_error(param%cutoff, param%hmat, param%vol, param%G_min, param%zet_min, param%l_mm, &
286 param%n_minimax, minimax_aw, param%err_mm, param%mm_delta, potential=potential, pot_par=pot_par)
288 DEALLOCATE (minimax_aw)
290 cpassert(param%zet_max + 1.0e-12 .GT. param%zet_min)
291 cpassert(param%n_grids .GE. 1)
293 cutoff_max = param%cutoff
294 cutoff_rel = param%cutoff/param%zet_max
295 cutoff_min = param%zet_min*cutoff_rel
297 CALL eri_mme_destroy_minimax_grids(param%minimax_grid)
298 ALLOCATE (param%minimax_grid(param%n_grids))
300 CALL eri_mme_create_minimax_grids(param%n_grids, param%minimax_grid, param%n_minimax, &
301 cutoff_max, cutoff_min, param%G_min, &
302 param%mm_delta, potential=potential, pot_par=pot_par)
318 SUBROUTINE eri_mme_create_minimax_grids(n_grids, minimax_grids, n_minimax, &
319 cutoff_max, cutoff_min, G_min, &
320 target_error, potential, pot_par)
321 INTEGER,
INTENT(IN) :: n_grids
322 TYPE(minimax_grid),
DIMENSION(n_grids), &
323 INTENT(OUT) :: minimax_grids
324 INTEGER,
INTENT(IN) :: n_minimax
325 REAL(kind=
dp),
INTENT(IN) :: cutoff_max, cutoff_min, g_min, &
327 INTEGER,
INTENT(IN),
OPTIONAL :: potential
328 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: pot_par
330 INTEGER :: i_grid, n_mm
331 REAL(kind=
dp) :: cutoff, cutoff_delta, err_mm, err_mm_prev
332 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: minimax_aw, minimax_aw_prev
334 cutoff_delta = (cutoff_max/cutoff_min)**(1.0_dp/(n_grids))
337 ALLOCATE (minimax_aw(2*n_minimax))
340 potential=potential, pot_par=pot_par)
341 cpassert(err_mm .LT. 1.1_dp*target_error + 1.0e-12)
342 CALL create_minimax_grid(minimax_grids(n_grids), cutoff, n_minimax, minimax_aw, err_mm)
343 DEALLOCATE (minimax_aw)
345 DO i_grid = n_grids - 1, 1, -1
346 DO n_mm = n_minimax, 1, -1
347 ALLOCATE (minimax_aw(2*n_mm))
349 potential=potential, pot_par=pot_par)
351 IF (err_mm .GT. 1.1_dp*target_error)
THEN
352 cpassert(n_mm .NE. n_minimax)
353 CALL create_minimax_grid(minimax_grids(i_grid), cutoff, n_mm + 1, minimax_aw_prev, err_mm_prev)
355 DEALLOCATE (minimax_aw)
359 IF (
ALLOCATED(minimax_aw_prev))
DEALLOCATE (minimax_aw_prev)
360 ALLOCATE (minimax_aw_prev(2*n_mm))
361 minimax_aw_prev(:) = minimax_aw(:)
362 DEALLOCATE (minimax_aw)
365 cutoff = cutoff/cutoff_delta
373 SUBROUTINE eri_mme_destroy_minimax_grids(minimax_grids)
374 TYPE(minimax_grid),
ALLOCATABLE,
DIMENSION(:), &
375 INTENT(INOUT) :: minimax_grids
379 IF (
ALLOCATED(minimax_grids))
THEN
380 DO igrid = 1,
SIZE(minimax_grids)
381 IF (
ASSOCIATED(minimax_grids(igrid)%minimax_aw))
THEN
382 DEALLOCATE (minimax_grids(igrid)%minimax_aw)
385 DEALLOCATE (minimax_grids)
397 SUBROUTINE create_minimax_grid(grid, cutoff, n_minimax, minimax_aw, error)
398 TYPE(minimax_grid),
INTENT(OUT) :: grid
399 REAL(kind=
dp),
INTENT(IN) :: cutoff
400 INTEGER,
INTENT(IN) :: n_minimax
401 REAL(kind=
dp),
DIMENSION(2*n_minimax),
INTENT(IN) :: minimax_aw
402 REAL(kind=
dp),
INTENT(IN) :: error
405 grid%n_minimax = n_minimax
406 ALLOCATE (grid%minimax_aw(2*n_minimax))
407 grid%minimax_aw(:) = minimax_aw(:)
421 TYPE(minimax_grid),
DIMENSION(:),
INTENT(IN) :: grids
422 REAL(kind=
dp),
INTENT(IN) :: cutoff
423 INTEGER,
INTENT(OUT) :: n_minimax
424 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT),
POINTER :: minimax_aw
425 INTEGER,
INTENT(OUT) :: grid_no
430 DO igrid = 1,
SIZE(grids)
431 IF (grids(igrid)%cutoff .GE. cutoff/2)
THEN
432 n_minimax = grids(igrid)%n_minimax
433 minimax_aw => grids(igrid)%minimax_aw
438 IF (grid_no == 0)
THEN
440 n_minimax = grids(igrid)%n_minimax
441 minimax_aw => grids(igrid)%minimax_aw
453 TYPE(minimax_grid),
INTENT(IN) :: grid
454 INTEGER,
INTENT(IN) :: grid_no, unit_nr
456 IF (unit_nr > 0)
THEN
457 WRITE (unit_nr,
'(T2, A, 1X, I2)')
"ERI_MME | Info for grid no.", grid_no
458 WRITE (unit_nr,
'(T2, A, 1X, ES9.2)')
"ERI_MME | Cutoff", grid%cutoff
459 WRITE (unit_nr,
'(T2, A, 1X, I2)')
"ERI_MME | Number of minimax points", grid%n_minimax
460 WRITE (unit_nr,
'(T2, A, 1X, 2ES9.2)')
"ERI_MME | minimax error", grid%error
471 TYPE(eri_mme_param),
INTENT(INOUT) :: param
473 IF (
ALLOCATED(param%minimax_grid))
THEN
474 CALL eri_mme_destroy_minimax_grids(param%minimax_grid)
real(kind=dp) function det_3x3(a)
...
Methods aiming for error estimate and automatic cutoff calibration. integrals.
subroutine, public calibrate_cutoff(hmat, h_inv, G_min, vol, zet_min, l_mm, zet_max, l_max_zet, n_minimax, cutoff_l, cutoff_r, tol, delta, cutoff, err_mm, err_c, C_mm, para_env, print_calib, unit_nr)
Find optimal cutoff minimizing errors due to minimax approximation and due to finite cutoff using bis...
subroutine, public minimax_error(cutoff, hmat, vol, G_min, zet_min, l_mm, n_minimax, minimax_aw, err_mm, delta_mm, potential, pot_par)
Minimax error, simple analytical formula Note minimax error may blow up for small exponents....
subroutine, public cutoff_minimax_error(cutoff, hmat, h_inv, vol, G_min, zet_min, l_mm, zet_max, l_max_zet, n_minimax, minimax_aw, err_mm, err_ctff, C_mm, para_env)
Compute upper bounds for the errors of 2-center ERI's (P|P) due to minimax approximation and due to f...
Methods related to properties of Hermite and Cartesian Gaussian functions.
integer, parameter, public eri_mme_longrange
integer, parameter, public eri_mme_coulomb
subroutine, public get_minimax_coeff_v_gspace(n_minimax, cutoff, G_min, minimax_aw, potential, pot_par, err_minimax)
Get minimax coefficient a_i and w_i for approximating 1/G^2 by sum_i w_i exp(-a_i G^2)
integer, parameter, public eri_mme_yukawa
Types and initialization / release routines for Minimax-Ewald method for electron repulsion integrals...
subroutine, public eri_mme_release(param)
...
subroutine, public get_minimax_from_cutoff(grids, cutoff, n_minimax, minimax_aw, grid_no)
...
subroutine, public eri_mme_init(param, n_minimax, cutoff, do_calib_cutoff, do_error_est, cutoff_min, cutoff_max, cutoff_eps, cutoff_delta, sum_precision, debug, debug_delta, debug_nsum, unit_nr, print_calib)
...
subroutine, public eri_mme_set_potential(param, potential, pot_par)
...
integer, parameter, public n_minimax_max
subroutine, public eri_mme_set_params(param, hmat, is_ortho, zet_min, zet_max, l_max_zet, l_max, para_env, potential, pot_par)
Set parameters for MME method with manual specification of basis parameters. Takes care of cutoff cal...
subroutine, public eri_mme_print_grid_info(grid, grid_no, unit_nr)
...
Some utility methods used in different contexts.
real(kind=dp) function, public g_abs_min(h_inv)
Find minimum length of G vectors, for a general (not necessarily orthorhombic) cell.
real(kind=dp) function, public r_abs_min(hmat)
Find minimum length of R vectors, for a general (not necessarily orthorhombic) cell.
Defines the basic variable types.
integer, parameter, public dp
Collection of simple mathematical functions and subroutines.
pure real(kind=dp) function, dimension(3, 3), public inv_3x3(a)
Returns the inverse of the 3 x 3 matrix a.
Interface to the message passing library MPI.
Provides Cartesian and spherical orbital pointers and indices.
subroutine, public init_orbital_pointers(maxl)
Initialize or update the orbital pointers.