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
75 TYPE(mp_para_env_type),
INTENT(IN) :: para_env
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)) .LE. tol) &
96 CALL cp_abort(__location__,
"difference of boundaries for cutoff "// &
97 "(MAX - MIN) must be greater than cutoff precision.")
99 IF ((delta .GE. 1.0_dp) .OR. (delta .LE. 0.0_dp)) &
100 CALL cp_abort(__location__, &
101 "relative delta to modify initial cutoff interval (DELTA) must be in (0, 1)")
103 cutoff_lr(1) = cutoff_l
104 cutoff_lr(2) = cutoff_r
106 ALLOCATE (minimax_aw(2*n_minimax))
109 WRITE (unit_nr,
'(/T2, A)')
"ERI_MME| Calibrating cutoff by bisecting error(minimax) - error(cutoff)"
110 WRITE (unit_nr,
'(T2, A, T72, ES9.2)')
"ERI_MME| Rel. cutoff precision", tol
111 WRITE (unit_nr,
'(T2, A, T77, F4.1)')
"ERI_MME| Rel. cutoff delta to modify initial interval", delta
115 DO iter1 = 1, max_iter + 1
116 IF (iter1 .GT. max_iter) &
117 CALL cp_abort(__location__, &
118 "Maximum number of iterations in bisection to determine initial "// &
119 "cutoff interval has been exceeded.")
121 cutoff_lr(1) = max(cutoff_lr(1), 0.5_dp*g_min**2)
125 CALL cutoff_minimax_error(cutoff_lr(i), hmat, h_inv, vol, g_min, zet_min, l_mm, zet_max, l_max_zet, &
126 n_minimax, minimax_aw, delta_mm(i), delta_c(i), c_mm, para_env)
129 valid_initial = .true.
130 IF ((delta_mm(1) - delta_c(1)) .GT. 0)
THEN
131 cutoff_lr(1) = cutoff_lr(1)*(1.0_dp - abs(delta))
132 valid_initial = .false.
134 IF ((delta_mm(2) - delta_c(2)) .LT. 0)
THEN
135 cutoff_lr(2) = cutoff_lr(2)*(1.0_dp + abs(delta))
136 valid_initial = .false.
139 IF (valid_initial)
EXIT
143 IF (do_print)
WRITE (unit_nr,
'(/T2, A)') &
144 "ERI_MME| Step, cutoff (min, max, mid), err(minimax), err(cutoff), err diff"
146 DO iter2 = 1, max_iter + 1
147 IF (iter2 .GT. max_iter) &
148 CALL cp_abort(__location__, &
149 "Maximum number of iterations in bisection to determine cutoff has been exceeded")
151 cutoff_mid = 0.5_dp*(cutoff_lr(1) + cutoff_lr(2))
152 CALL cutoff_minimax_error(cutoff_mid, hmat, h_inv, vol, g_min, zet_min, l_mm, zet_max, l_max_zet, &
153 n_minimax, minimax_aw, delta_mm_mid, delta_c_mid, c_mm, para_env)
154 IF (do_print)
WRITE (unit_nr,
'(T11, I2, F11.1, F11.1, F11.1, 3X, ES9.2, 3X, ES9.2, 3X, ES9.2)') &
155 iter2, cutoff_lr(1), cutoff_lr(2), cutoff_mid, &
156 delta_mm_mid, delta_c_mid, delta_mm_mid - delta_c_mid
158 IF ((cutoff_lr(2) - cutoff_lr(1))/cutoff_mid .LT. tol)
EXIT
159 IF (delta_mm_mid - delta_c_mid .GT. 0)
THEN
160 cutoff_lr(2) = cutoff_mid
161 delta_mm(2) = delta_mm_mid
162 delta_c(2) = delta_c_mid
164 cutoff_lr(1) = cutoff_mid
165 delta_mm(1) = delta_mm_mid
166 delta_c(1) = delta_c_mid
169 err_mm = delta_mm_mid
174 WRITE (unit_nr,
'(/T2, A)')
"ERI_MME| Cutoff calibration number of steps:"
175 WRITE (unit_nr,
'(T2, A, T79, I2)')
"ERI_MME| Steps for initial interval", iter1 - 1
176 WRITE (unit_nr,
'(T2, A, T79, I2/)')
"ERI_MME| Bisection iteration steps", iter2 - 1
203 n_minimax, minimax_aw, err_mm, err_ctff, C_mm, para_env)
204 REAL(kind=
dp),
INTENT(IN) :: cutoff
205 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: hmat, h_inv
206 REAL(kind=
dp),
INTENT(IN) :: vol, g_min, zet_min
207 INTEGER,
INTENT(IN) :: l_mm
208 REAL(kind=
dp),
INTENT(IN) :: zet_max
209 INTEGER,
INTENT(IN) :: l_max_zet, n_minimax
210 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: minimax_aw
211 REAL(kind=
dp),
INTENT(OUT) :: err_mm, err_ctff, c_mm
212 TYPE(mp_para_env_type),
INTENT(IN) :: para_env
214 REAL(kind=
dp) :: delta_mm
216 CALL minimax_error(cutoff, hmat, vol, g_min, zet_min, l_mm, &
217 n_minimax, minimax_aw, err_mm, delta_mm)
218 CALL cutoff_error(cutoff, h_inv, g_min, zet_max, l_max_zet, &
219 n_minimax, minimax_aw, err_ctff, c_mm, para_env)
241 n_minimax, minimax_aw, err_mm, delta_mm, potential, pot_par)
242 REAL(kind=
dp),
INTENT(IN) :: cutoff
243 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: hmat
244 REAL(kind=
dp),
INTENT(IN) :: vol, g_min, zet_min
245 INTEGER,
INTENT(IN) :: l_mm, n_minimax
246 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: minimax_aw
247 REAL(kind=
dp),
INTENT(OUT) :: err_mm, delta_mm
248 INTEGER,
INTENT(IN),
OPTIONAL :: potential
249 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: pot_par
252 REAL(kind=
dp) :: prod_mm_k
255 potential=potential, pot_par=pot_par, err_minimax=delta_mm)
259 prod_mm_k = prod_mm_k*(abs(hmat(i_xyz, i_xyz))/
twopi + &
260 merge(sqrt(2.0_dp/(zet_min*
pi))*exp(-1.0_dp), 0.0_dp, l_mm .GT. 0))
262 err_mm = 32*
pi**4/vol*delta_mm*prod_mm_k
286 n_minimax, minimax_aw, err_ctff, C_mm, para_env)
287 REAL(kind=
dp),
INTENT(IN) :: cutoff
288 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: h_inv
289 REAL(kind=
dp),
INTENT(IN) :: g_min, zet_max
290 INTEGER,
INTENT(IN) :: l_max_zet, n_minimax
291 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: minimax_aw
292 REAL(kind=
dp),
INTENT(OUT) :: err_ctff, c_mm
293 TYPE(mp_para_env_type),
INTENT(IN) :: para_env
295 INTEGER :: i_aw, ig, iter, max_iter, ng
296 REAL(kind=
dp) :: c, dg, eps_zet, err0, err1, err_c, err_ctff_curr, err_ctff_prev, err_d, g, &
297 g_1, g_c, gr, zet_a, zet_b, zet_c, zet_d, zet_div, zet_max_tmp
304 g_c = sqrt(2.0*cutoff)
306 zet_max_tmp = zet_max
313 g_1 = sqrt(1.0_dp/(3.0_dp*minval(minimax_aw(1:n_minimax))))
316 IF (g_1 .GT. g_c)
THEN
323 DO i_aw = 1, n_minimax
324 c = c + 3.0_dp*minimax_aw(n_minimax + i_aw)*exp(-3.0_dp*minimax_aw(i_aw)*g**2)*g**2
330 DO i_aw = 1, n_minimax
331 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
334 c = max(1.0_dp, c_mm)
336 err_ctff_prev = 0.0_dp
337 gr = 0.5_dp*(sqrt(5.0_dp) - 1.0_dp)
339 DO iter = 1, max_iter + 1
340 IF (iter .GT. max_iter) &
341 CALL cp_abort(__location__,
"Maximum number of iterations for finding "// &
342 "exponent maximizing cutoff error has been exceeded.")
344 CALL cutoff_error_fixed_exp(cutoff, h_inv, g_min, l_max_zet, zet_max_tmp, c, err_ctff_curr, para_env)
345 IF (err_ctff_prev .GE. err_ctff_curr)
THEN
347 zet_b = min(zet_max_tmp*zet_div**2, zet_max)
350 err_ctff_prev = err_ctff_curr
352 zet_max_tmp = zet_max_tmp/zet_div
356 zet_c = zet_b - gr*(zet_b - zet_a)
357 zet_d = zet_a + gr*(zet_b - zet_a)
358 DO iter = 1, max_iter + 1
359 IF (abs(zet_c - zet_d) .LT. eps_zet*(zet_a + zet_b))
THEN
360 CALL cutoff_error_fixed_exp(cutoff, h_inv, g_min, l_max_zet, zet_a, c, err0, para_env)
361 CALL cutoff_error_fixed_exp(cutoff, h_inv, g_min, l_max_zet, zet_b, c, err1, para_env)
362 err_ctff_curr = max(err0, err1)
365 CALL cutoff_error_fixed_exp(cutoff, h_inv, g_min, l_max_zet, zet_c, c, err_c, para_env)
366 CALL cutoff_error_fixed_exp(cutoff, h_inv, g_min, l_max_zet, zet_d, c, err_d, para_env)
367 IF (err_c .GT. err_d)
THEN
370 zet_c = zet_b - gr*(zet_b - zet_a)
374 zet_d = zet_a + gr*(zet_b - zet_a)
377 err_ctff = err_ctff_curr
395 SUBROUTINE cutoff_error_fixed_exp(cutoff, h_inv, G_min, l_max_zet, zet_max, C_mm, err_c, para_env)
396 REAL(kind=
dp),
INTENT(IN) :: cutoff
397 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: h_inv
398 REAL(kind=
dp),
INTENT(IN) :: g_min
399 INTEGER,
INTENT(IN) :: l_max_zet
400 REAL(kind=
dp),
INTENT(IN) :: zet_max, c_mm
401 REAL(kind=
dp),
INTENT(OUT) :: err_c
402 TYPE(mp_para_env_type),
INTENT(IN) :: para_env
404 INTEGER :: ax, ay, az, g_l, g_u, gl_first, gl_last, &
405 gu_first, gu_last, i_xyz, l, my_p, &
406 n_gl, n_gl_left, n_gl_p, n_gu, &
407 n_gu_left, n_gu_p, n_p
408 REAL(kind=
dp) :: alpha_g, eps_g, err_c_l, g_c, g_rad, &
409 g_res, inv_lgth, prefactor, sum_g_diff
410 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: s_g_l, s_g_u
412 g_c = sqrt(2.0_dp*cutoff)
417 alpha_g = 1.0_dp/(2.0_dp*zet_max)
418 prefactor = 1.0_dp/zet_max
420 ALLOCATE (s_g_l(0:2*l_max_zet, 3))
421 ALLOCATE (s_g_u(0:2*l_max_zet, 3))
423 g_rad =
exp_radius(2*l_max_zet, alpha_g, eps_g, prefactor, epsabs=g_res)
426 my_p = para_env%mepos
427 n_p = para_env%num_pe
430 inv_lgth = abs(h_inv(i_xyz, i_xyz))
432 g_l = floor(g_c/(inv_lgth*
twopi))
433 g_u = floor(g_rad/(inv_lgth*
twopi))
435 IF (g_u .LT. g_l) g_u = g_l
446 n_gu = max((g_u - g_l), 0)
450 n_gu_left = mod(n_gu, n_p)
451 n_gl_left = mod(n_gl, n_p)
453 IF (my_p .LT. n_gu_left)
THEN
454 gu_first = g_l + 1 + (n_gu_p + 1)*my_p
455 gu_last = g_l + 1 + (n_gu_p + 1)*(my_p + 1) - 1
457 gu_first = g_l + 1 + n_gu_left + n_gu_p*my_p
458 gu_last = g_l + 1 + n_gu_left + n_gu_p*(my_p + 1) - 1
461 IF (my_p .LT. n_gl_left)
THEN
462 gl_first = -g_l + (n_gl_p + 1)*my_p
463 gl_last = -g_l + (n_gl_p + 1)*(my_p + 1) - 1
465 gl_first = -g_l + n_gl_left + n_gl_p*my_p
466 gl_last = -g_l + n_gl_left + n_gl_p*(my_p + 1) - 1
471 2.0_dp/3.0_dp, prefactor)
475 2.0_dp/3.0_dp, prefactor)
478 CALL para_env%sum(s_g_l)
479 CALL para_env%sum(s_g_u)
490 sum_g_diff = s_g_u(2*ax, 1)*s_g_u(2*ay, 2)*s_g_u(2*az, 3) + &
491 s_g_u(2*ax, 1)*s_g_u(2*ay, 2)*s_g_l(2*az, 3) + &
492 s_g_u(2*ax, 1)*s_g_l(2*ay, 2)*s_g_u(2*az, 3) + &
493 s_g_l(2*ax, 1)*s_g_u(2*ay, 2)*s_g_u(2*az, 3) + &
494 s_g_u(2*ax, 1)*s_g_l(2*ay, 2)*s_g_l(2*az, 3) + &
495 s_g_l(2*ax, 1)*s_g_u(2*ay, 2)*s_g_l(2*az, 3) + &
496 s_g_l(2*ax, 1)*s_g_l(2*ay, 2)*s_g_u(2*az, 3)
499 c_mm/3.0_dp*sum_g_diff
501 err_c = max(err_c, err_c_l)
506 DEALLOCATE (s_g_u, s_g_l)
508 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 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...
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 ...
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.