25#include "../base/base_uses.f90"
31 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .false.
33 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'eri_mme_error_control'
63 SUBROUTINE calibrate_cutoff(hmat, h_inv, G_min, vol, zet_min, l_mm, zet_max, l_max_zet, &
64 n_minimax, cutoff_l, cutoff_r, tol, delta, &
65 cutoff, err_mm, err_c, C_mm, para_env, print_calib, unit_nr)
66 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: hmat, h_inv
67 REAL(kind=
dp),
INTENT(IN) :: g_min
69 REAL(kind=
dp),
INTENT(IN) :: zet_min
70 INTEGER,
INTENT(IN) :: l_mm
71 REAL(kind=
dp),
INTENT(IN) :: zet_max
72 INTEGER,
INTENT(IN) :: l_max_zet, n_minimax
73 REAL(kind=
dp),
INTENT(IN) :: cutoff_l, cutoff_r, tol, delta
74 REAL(kind=
dp),
INTENT(OUT) :: cutoff, err_mm, err_c, c_mm
76 LOGICAL,
INTENT(IN) :: print_calib
77 INTEGER,
INTENT(IN) :: unit_nr
79 INTEGER :: i, iter1, iter2, max_iter
80 LOGICAL :: do_print, valid_initial
81 REAL(kind=
dp) :: cutoff_mid, delta_c_mid, delta_mm_mid
82 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: minimax_aw
83 REAL(kind=
dp),
DIMENSION(2) :: cutoff_lr, delta_c, delta_mm
85 do_print = unit_nr > 0 .AND. print_calib
87 WRITE (unit_nr,
'(/T2, A)')
"ERI_MME| Basis set parameters for estimating minimax error"
88 WRITE (unit_nr,
'(T2, A, T67, ES12.2, 1X, I1)')
"ERI_MME| exp, l:", zet_min, l_mm
89 WRITE (unit_nr,
'(T2, A)')
"ERI_MME| Basis set parameters for estimating cutoff error"
90 WRITE (unit_nr,
'(T2, A, T67, ES12.2, 1X, I1)')
"ERI_MME| exp, l:", zet_max, l_max_zet
95 IF ((cutoff_r - cutoff_l)/(0.5_dp*(cutoff_r + cutoff_l)) <= tol)
THEN
96 CALL cp_abort(__location__,
"difference of boundaries for cutoff "// &
97 "(MAX - MIN) must be greater than cutoff precision.")
100 IF ((delta >= 1.0_dp) .OR. (delta <= 0.0_dp))
THEN
101 CALL cp_abort(__location__, &
102 "relative delta to modify initial cutoff interval (DELTA) must be in (0, 1)")
105 cutoff_lr(1) = cutoff_l
106 cutoff_lr(2) = cutoff_r
108 ALLOCATE (minimax_aw(2*n_minimax))
111 WRITE (unit_nr,
'(/T2, A)')
"ERI_MME| Calibrating cutoff by bisecting error(minimax) - error(cutoff)"
112 WRITE (unit_nr,
'(T2, A, T72, ES9.2)')
"ERI_MME| Rel. cutoff precision", tol
113 WRITE (unit_nr,
'(T2, A, T77, F4.1)')
"ERI_MME| Rel. cutoff delta to modify initial interval", delta
117 DO iter1 = 1, max_iter + 1
118 IF (iter1 > max_iter)
THEN
119 CALL cp_abort(__location__, &
120 "Maximum number of iterations in bisection to determine initial "// &
121 "cutoff interval has been exceeded.")
124 cutoff_lr(1) = max(cutoff_lr(1), 0.5_dp*g_min**2)
128 CALL cutoff_minimax_error(cutoff_lr(i), hmat, h_inv, vol, g_min, zet_min, l_mm, zet_max, l_max_zet, &
129 n_minimax, minimax_aw, delta_mm(i), delta_c(i), c_mm, para_env)
132 valid_initial = .true.
133 IF ((delta_mm(1) - delta_c(1)) > 0)
THEN
134 cutoff_lr(1) = cutoff_lr(1)*(1.0_dp - abs(delta))
135 valid_initial = .false.
137 IF ((delta_mm(2) - delta_c(2)) < 0)
THEN
138 cutoff_lr(2) = cutoff_lr(2)*(1.0_dp + abs(delta))
139 valid_initial = .false.
142 IF (valid_initial)
EXIT
146 IF (do_print)
WRITE (unit_nr,
'(/T2, A)') &
147 "ERI_MME| Step, cutoff (min, max, mid), err(minimax), err(cutoff), err diff"
149 DO iter2 = 1, max_iter + 1
150 IF (iter2 > max_iter)
THEN
151 CALL cp_abort(__location__, &
152 "Maximum number of iterations in bisection to determine cutoff has been exceeded")
155 cutoff_mid = 0.5_dp*(cutoff_lr(1) + cutoff_lr(2))
156 CALL cutoff_minimax_error(cutoff_mid, hmat, h_inv, vol, g_min, zet_min, l_mm, zet_max, l_max_zet, &
157 n_minimax, minimax_aw, delta_mm_mid, delta_c_mid, c_mm, para_env)
158 IF (do_print)
WRITE (unit_nr,
'(T11, I2, F11.1, F11.1, F11.1, 3X, ES9.2, 3X, ES9.2, 3X, ES9.2)') &
159 iter2, cutoff_lr(1), cutoff_lr(2), cutoff_mid, &
160 delta_mm_mid, delta_c_mid, delta_mm_mid - delta_c_mid
162 IF ((cutoff_lr(2) - cutoff_lr(1))/cutoff_mid < tol)
EXIT
163 IF (delta_mm_mid - delta_c_mid > 0)
THEN
164 cutoff_lr(2) = cutoff_mid
165 delta_mm(2) = delta_mm_mid
166 delta_c(2) = delta_c_mid
168 cutoff_lr(1) = cutoff_mid
169 delta_mm(1) = delta_mm_mid
170 delta_c(1) = delta_c_mid
173 err_mm = delta_mm_mid
178 WRITE (unit_nr,
'(/T2, A)')
"ERI_MME| Cutoff calibration number of steps:"
179 WRITE (unit_nr,
'(T2, A, T79, I2)')
"ERI_MME| Steps for initial interval", iter1 - 1
180 WRITE (unit_nr,
'(T2, A, T79, I2/)')
"ERI_MME| Bisection iteration steps", iter2 - 1
207 n_minimax, minimax_aw, err_mm, err_ctff, C_mm, para_env)
208 REAL(kind=
dp),
INTENT(IN) :: cutoff
209 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: hmat, h_inv
210 REAL(kind=
dp),
INTENT(IN) :: vol, g_min, zet_min
211 INTEGER,
INTENT(IN) :: l_mm
212 REAL(kind=
dp),
INTENT(IN) :: zet_max
213 INTEGER,
INTENT(IN) :: l_max_zet, n_minimax
214 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: minimax_aw
215 REAL(kind=
dp),
INTENT(OUT) :: err_mm, err_ctff, c_mm
218 REAL(kind=
dp) :: delta_mm
220 CALL minimax_error(cutoff, hmat, vol, g_min, zet_min, l_mm, &
221 n_minimax, minimax_aw, err_mm, delta_mm)
222 CALL cutoff_error(cutoff, h_inv, g_min, zet_max, l_max_zet, &
223 n_minimax, minimax_aw, err_ctff, c_mm, para_env)
245 n_minimax, minimax_aw, err_mm, delta_mm, potential, pot_par)
246 REAL(kind=
dp),
INTENT(IN) :: cutoff
247 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: hmat
248 REAL(kind=
dp),
INTENT(IN) :: vol, g_min, zet_min
249 INTEGER,
INTENT(IN) :: l_mm, n_minimax
250 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: minimax_aw
251 REAL(kind=
dp),
INTENT(OUT) :: err_mm, delta_mm
252 INTEGER,
INTENT(IN),
OPTIONAL :: potential
253 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: pot_par
256 REAL(kind=
dp) :: prod_mm_k
259 potential=potential, pot_par=pot_par, err_minimax=delta_mm)
263 prod_mm_k = prod_mm_k*(abs(hmat(i_xyz, i_xyz))/
twopi + &
264 merge(sqrt(2.0_dp/(zet_min*
pi))*exp(-1.0_dp), 0.0_dp, l_mm > 0))
266 err_mm = 32*
pi**4/vol*delta_mm*prod_mm_k
290 n_minimax, minimax_aw, err_ctff, C_mm, para_env)
291 REAL(kind=
dp),
INTENT(IN) :: cutoff
292 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: h_inv
293 REAL(kind=
dp),
INTENT(IN) :: g_min, zet_max
294 INTEGER,
INTENT(IN) :: l_max_zet, n_minimax
295 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: minimax_aw
296 REAL(kind=
dp),
INTENT(OUT) :: err_ctff, c_mm
299 INTEGER :: i_aw, ig, iter, max_iter, ng
300 REAL(kind=
dp) :: c, dg, eps_zet, err0, err1, err_c, err_ctff_curr, err_ctff_prev, err_d, g, &
301 g_1, g_c, gr, zet_a, zet_b, zet_c, zet_d, zet_div, zet_max_tmp
308 g_c = sqrt(2.0*cutoff)
310 zet_max_tmp = zet_max
317 g_1 = sqrt(1.0_dp/(3.0_dp*minval(minimax_aw(1:n_minimax))))
327 DO i_aw = 1, n_minimax
328 c = c + 3.0_dp*minimax_aw(n_minimax + i_aw)*exp(-3.0_dp*minimax_aw(i_aw)*g**2)*g**2
334 DO i_aw = 1, n_minimax
335 c_mm = c_mm + 3.0_dp*minimax_aw(n_minimax + i_aw)*exp(-3.0_dp*minimax_aw(i_aw)*g_c**2)*g_c**2
338 c = max(1.0_dp, c_mm)
340 err_ctff_prev = 0.0_dp
341 gr = 0.5_dp*(sqrt(5.0_dp) - 1.0_dp)
343 DO iter = 1, max_iter + 1
344 IF (iter > max_iter)
THEN
345 CALL cp_abort(__location__,
"Maximum number of iterations for finding "// &
346 "exponent maximizing cutoff error has been exceeded.")
349 CALL cutoff_error_fixed_exp(cutoff, h_inv, g_min, l_max_zet, zet_max_tmp, c, err_ctff_curr, para_env)
350 IF (err_ctff_prev >= err_ctff_curr)
THEN
352 zet_b = min(zet_max_tmp*zet_div**2, zet_max)
355 err_ctff_prev = err_ctff_curr
357 zet_max_tmp = zet_max_tmp/zet_div
361 zet_c = zet_b - gr*(zet_b - zet_a)
362 zet_d = zet_a + gr*(zet_b - zet_a)
363 DO iter = 1, max_iter + 1
364 IF (abs(zet_c - zet_d) < eps_zet*(zet_a + zet_b))
THEN
365 CALL cutoff_error_fixed_exp(cutoff, h_inv, g_min, l_max_zet, zet_a, c, err0, para_env)
366 CALL cutoff_error_fixed_exp(cutoff, h_inv, g_min, l_max_zet, zet_b, c, err1, para_env)
367 err_ctff_curr = max(err0, err1)
370 CALL cutoff_error_fixed_exp(cutoff, h_inv, g_min, l_max_zet, zet_c, c, err_c, para_env)
371 CALL cutoff_error_fixed_exp(cutoff, h_inv, g_min, l_max_zet, zet_d, c, err_d, para_env)
372 IF (err_c > err_d)
THEN
375 zet_c = zet_b - gr*(zet_b - zet_a)
379 zet_d = zet_a + gr*(zet_b - zet_a)
382 err_ctff = err_ctff_curr
400 SUBROUTINE cutoff_error_fixed_exp(cutoff, h_inv, G_min, l_max_zet, zet_max, C_mm, err_c, para_env)
401 REAL(kind=
dp),
INTENT(IN) :: cutoff
402 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: h_inv
403 REAL(kind=
dp),
INTENT(IN) :: g_min
404 INTEGER,
INTENT(IN) :: l_max_zet
405 REAL(kind=
dp),
INTENT(IN) :: zet_max, c_mm
406 REAL(kind=
dp),
INTENT(OUT) :: err_c
409 INTEGER :: ax, ay, az, g_l, g_u, gl_first, gl_last, &
410 gu_first, gu_last, i_xyz, l, my_p, &
411 n_gl, n_gl_left, n_gl_p, n_gu, &
412 n_gu_left, n_gu_p, n_p
413 REAL(kind=
dp) :: alpha_g, eps_g, err_c_l, g_c, g_rad, &
414 g_res, inv_lgth, prefactor, sum_g_diff
415 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: s_g_l, s_g_u
417 g_c = sqrt(2.0_dp*cutoff)
422 alpha_g = 1.0_dp/(2.0_dp*zet_max)
423 prefactor = 1.0_dp/zet_max
425 ALLOCATE (s_g_l(0:2*l_max_zet, 3))
426 ALLOCATE (s_g_u(0:2*l_max_zet, 3))
428 g_rad =
exp_radius(2*l_max_zet, alpha_g, eps_g, prefactor, epsabs=g_res)
431 my_p = para_env%mepos
432 n_p = para_env%num_pe
435 inv_lgth = abs(h_inv(i_xyz, i_xyz))
437 g_l = floor(g_c/(inv_lgth*
twopi))
438 g_u = floor(g_rad/(inv_lgth*
twopi))
440 IF (g_u < g_l) g_u = g_l
451 n_gu = max((g_u - g_l), 0)
455 n_gu_left = mod(n_gu, n_p)
456 n_gl_left = mod(n_gl, n_p)
458 IF (my_p < n_gu_left)
THEN
459 gu_first = g_l + 1 + (n_gu_p + 1)*my_p
460 gu_last = g_l + 1 + (n_gu_p + 1)*(my_p + 1) - 1
462 gu_first = g_l + 1 + n_gu_left + n_gu_p*my_p
463 gu_last = g_l + 1 + n_gu_left + n_gu_p*(my_p + 1) - 1
466 IF (my_p < n_gl_left)
THEN
467 gl_first = -g_l + (n_gl_p + 1)*my_p
468 gl_last = -g_l + (n_gl_p + 1)*(my_p + 1) - 1
470 gl_first = -g_l + n_gl_left + n_gl_p*my_p
471 gl_last = -g_l + n_gl_left + n_gl_p*(my_p + 1) - 1
476 2.0_dp/3.0_dp, prefactor)
480 2.0_dp/3.0_dp, prefactor)
483 CALL para_env%sum(s_g_l)
484 CALL para_env%sum(s_g_u)
495 sum_g_diff = s_g_u(2*ax, 1)*s_g_u(2*ay, 2)*s_g_u(2*az, 3) + &
496 s_g_u(2*ax, 1)*s_g_u(2*ay, 2)*s_g_l(2*az, 3) + &
497 s_g_u(2*ax, 1)*s_g_l(2*ay, 2)*s_g_u(2*az, 3) + &
498 s_g_l(2*ax, 1)*s_g_u(2*ay, 2)*s_g_u(2*az, 3) + &
499 s_g_u(2*ax, 1)*s_g_l(2*ay, 2)*s_g_l(2*az, 3) + &
500 s_g_l(2*ax, 1)*s_g_u(2*ay, 2)*s_g_l(2*az, 3) + &
501 s_g_l(2*ax, 1)*s_g_l(2*ay, 2)*s_g_u(2*az, 3)
504 c_mm/3.0_dp*sum_g_diff
506 err_c = max(err_c, err_c_l)
511 DEALLOCATE (s_g_u, s_g_l)
513 END SUBROUTINE cutoff_error_fixed_exp
All kind of helpful little routines.
real(kind=dp) function, public exp_radius(l, alpha, threshold, prefactor, epsabs, epsrel, rlow)
The radius of a primitive Gaussian function for a given threshold is calculated. g(r) = prefactor*r**...
Methods aiming for error estimate and automatic cutoff calibration. integrals.
subroutine, public cutoff_error(cutoff, h_inv, g_min, zet_max, l_max_zet, n_minimax, minimax_aw, err_ctff, c_mm, para_env)
Cutoff error, estimating G > G_c part of Ewald sum by using C/3 * 1/(Gx^2*Gy^2*Gz^2)^1/3 as an upper ...
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...
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....
Methods related to properties of Hermite and Cartesian Gaussian functions.
pure real(kind=dp) function, public hermite_gauss_norm(zet, l)
Norm of 1d Hermite-Gauss functions.
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)
Ewald sums to represent integrals in direct and reciprocal lattice.
pure subroutine, public pgf_sum_2c_gspace_1d_deltal(s_g, alpha, inv_lgth, g_min, g_c, delta_l, prefactor)
Compute 1d sum S_G(l, alpha) = inv_lgth*sum_G( C(l, alpha, delta_l, G) ) with C(l,...
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
real(kind=dp), parameter, public twopi
Interface to the message passing library MPI.
stores all the informations relevant to an mpi environment