36#include "./base/base_uses.f90"
41 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'gw_optimize_ri_rs_grid'
42 REAL(KIND=
dp),
PARAMETER,
PRIVATE :: optimizer_accuracy = 1.0e-9_dp
43 REAL(KIND=
dp),
PARAMETER,
PRIVATE :: truncated_coulomb_cutoff = 3.0_dp/
angstrom
45 TYPE :: local_cluster_type
46 INTEGER,
ALLOCATABLE :: atoms(:)
47 REAL(KIND=
dp),
ALLOCATABLE :: three_center(:, :, :)
48 END TYPE local_cluster_type
63 CHARACTER(len=*),
PARAMETER :: routinen =
'optimize_ri_rs_grid'
65 INTEGER :: handle, iatom, ikind, n_variable, &
67 INTEGER,
ALLOCATABLE :: ao_size(:), grid_offsets(:), ri_size(:)
69 REAL(kind=
dp) :: f, maximum_absolute_error
70 REAL(kind=
dp),
ALLOCATABLE :: g(:), lower(:), upper(:), x(:)
73 TYPE(local_cluster_type),
ALLOCATABLE :: clusters(:)
77 CALL timeset(routinen, handle)
78 NULLIFY (cell, para_env, particle_set)
79 cell => bs_env%ri_rs%cell
80 particle_set => bs_env%ri_rs%particle_set
81 para_env => bs_env%para_env
82 cpassert(
ASSOCIATED(cell))
83 cpassert(
ASSOCIATED(particle_set))
84 cpassert(
ASSOCIATED(para_env))
85 cpassert(
ALLOCATED(bs_env%basis_set_AO))
86 cpassert(
ALLOCATED(bs_env%basis_set_RI))
87 cpassert(
ALLOCATED(bs_env%ri_rs%grid_cache))
89 IF (bs_env%ri_rs%grid_opt%max_iter < 1)
THEN
90 cpabort(
"GRID_OPTIMIZATION%MAX_ITER must be positive")
92 IF (bs_env%ri_rs%grid_opt%cutoff_atomic_cluster <= 0.0_dp)
THEN
93 cpabort(
"GRID_OPTIMIZATION%CUTOFF_ATOMIC_CLUSTER must be positive")
95 IF (bs_env%ri_rs%tikhonov < 0.0_dp)
THEN
96 cpabort(
"RI_RS%TIKHONOV must not be negative")
99 CALL get_cell(cell, periodic=periodic)
101 cpabort(
"GRID_OPTIMIZATION currently supports nonperiodic local environments only")
104 unit_nr = bs_env%unit_nr
105 ALLOCATE (ao_size(
SIZE(particle_set)), ri_size(
SIZE(particle_set)))
106 DO iatom = 1,
SIZE(particle_set)
107 ikind = particle_set(iatom)%atomic_kind%kind_number
108 cpassert(
ASSOCIATED(bs_env%basis_set_AO(ikind)%gto_basis_set))
109 cpassert(
ASSOCIATED(bs_env%basis_set_RI(ikind)%gto_basis_set))
110 ao_size(iatom) = bs_env%basis_set_AO(ikind)%gto_basis_set%nsgf
111 ri_size(iatom) = bs_env%basis_set_RI(ikind)%gto_basis_set%nsgf
113 IF (any(ao_size < 1) .OR. any(ri_size < 1))
THEN
114 cpabort(
"Every atom in GRID_OPTIMIZATION needs ORB and RI_AUX functions")
117 cpassert(
SIZE(bs_env%ri_rs%grid_cache) ==
SIZE(particle_set))
118 ALLOCATE (grid_offsets(
SIZE(bs_env%ri_rs%grid_cache)))
120 DO iatom = 1,
SIZE(bs_env%ri_rs%grid_cache)
121 grid_offsets(iatom) = n_variable
122 n_variable = n_variable + 3*
SIZE(bs_env%ri_rs%grid_cache(iatom)%raw_points, 2)
125 TYPE(libint_potential_type) :: potential
127 potential%cutoff_radius = truncated_coulomb_cutoff
128 potential%omega = 0.0_dp
129 potential%filename =
"t_c_g.dat"
131 bs_env%basis_set_AO, bs_env%basis_set_AO, bs_env%basis_set_RI)
133 CALL build_local_clusters(integral_context, particle_set, cell, ao_size, ri_size, &
134 bs_env%ri_rs%grid_opt%cutoff_atomic_cluster, para_env, clusters)
136 ALLOCATE (x(n_variable), g(n_variable), lower(n_variable), upper(n_variable))
137 CALL pack_atom_grids(bs_env%ri_rs%grid_cache, grid_offsets, x)
140 CALL optimize_grid_coordinates(x, lower, upper, optimizer_accuracy, &
141 bs_env%ri_rs%grid_opt%max_iter, bs_env, clusters, grid_offsets)
142 CALL grid_objective(x, bs_env, clusters, grid_offsets, f, g, &
143 maximum_absolute_error, successful)
144 IF (.NOT. successful) cpabort(
"RI-RS grid optimization produced no regularized fit")
146 IF (unit_nr > 0)
THEN
147 WRITE (unit_nr,
'(/,T2,A)')
'RI-RS grid optimization terminated'
148 WRITE (unit_nr,
'(T2,A,T72,ES9.1)')
'Normalized 3C error:', f
149 WRITE (unit_nr,
'(T2,A,T72,ES9.1)') &
150 'Maximum absolute 3C error:', maximum_absolute_error
153 DO iatom = 1,
SIZE(bs_env%ri_rs%grid_cache)
154 bs_env%ri_rs%grid_cache(iatom)%npts = &
155 SIZE(bs_env%ri_rs%grid_cache(iatom)%raw_points, 2)
157 IF (unit_nr > 0)
FLUSH (unit_nr)
159 bs_env%ri_rs%Z_lP_exists = .false.
161 CALL timestop(handle)
176 SUBROUTINE grid_objective(coordinates, bs_env, clusters, grid_offsets, value, gradient, &
177 maximum_absolute_error, valid)
178 REAL(kind=dp),
DIMENSION(:),
INTENT(IN) :: coordinates
179 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
180 TYPE(local_cluster_type),
DIMENSION(:),
INTENT(IN) :: clusters
181 INTEGER,
DIMENSION(:),
INTENT(IN) :: grid_offsets
182 REAL(kind=dp),
INTENT(OUT) ::
value
183 REAL(kind=dp),
DIMENSION(:),
INTENT(OUT) :: gradient
184 REAL(kind=dp),
INTENT(OUT) :: maximum_absolute_error
185 LOGICAL,
INTENT(OUT) :: valid
187 INTEGER :: all_valid, icluster, successful_clusters
188 REAL(kind=dp) :: cluster_maximum_absolute_error, &
190 REAL(kind=dp),
ALLOCATABLE :: cluster_gradient(:, :)
191 TYPE(cell_type),
POINTER :: cell
192 TYPE(mp_para_env_type),
POINTER :: para_env
193 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
195 cell => bs_env%ri_rs%cell
196 particle_set => bs_env%ri_rs%particle_set
197 para_env => bs_env%para_env
198 CALL unpack_atom_grids(coordinates, bs_env%ri_rs%grid_cache, grid_offsets)
201 successful_clusters = 0
202 maximum_absolute_error = 0.0_dp
204 DO icluster = 1,
SIZE(clusters)
205 CALL evaluate_local_cluster(clusters(icluster), bs_env%ri_rs%grid_cache, &
206 bs_env, particle_set, cell, &
207 cluster_value, cluster_gradient, &
208 cluster_maximum_absolute_error, valid)
209 IF (.NOT. valid)
THEN
210 IF (
ALLOCATED(cluster_gradient))
DEALLOCATE (cluster_gradient)
213 value =
value + cluster_value
214 CALL accumulate_atom_gradient(clusters(icluster)%atoms, bs_env%ri_rs%grid_cache, &
215 grid_offsets, cluster_gradient, gradient)
216 successful_clusters = successful_clusters + 1
217 maximum_absolute_error = &
218 max(maximum_absolute_error, cluster_maximum_absolute_error)
219 DEALLOCATE (cluster_gradient)
221 all_valid = merge(1, 0, valid)
222 CALL para_env%sum(
value)
223 CALL para_env%sum(gradient)
224 CALL para_env%sum(successful_clusters)
225 CALL para_env%sum(all_valid)
226 CALL para_env%max(maximum_absolute_error)
227 valid = successful_clusters ==
SIZE(particle_set) .AND. all_valid == para_env%num_pe
228 IF (.NOT. valid)
THEN
233 value =
value/real(
SIZE(particle_set), dp)
234 gradient = gradient/real(
SIZE(particle_set), dp)
235 END SUBROUTINE grid_objective
248 SUBROUTINE optimize_grid_coordinates(x, lower, upper, accuracy, max_evaluations, &
249 bs_env, clusters, grid_offsets)
250 REAL(kind=dp),
DIMENSION(:),
INTENT(INOUT) :: x
251 REAL(kind=dp),
DIMENSION(:),
INTENT(IN) :: lower, upper
252 REAL(kind=dp),
INTENT(IN) :: accuracy
253 INTEGER,
INTENT(IN) :: max_evaluations
254 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
255 TYPE(local_cluster_type),
DIMENSION(:),
INTENT(IN) :: clusters
256 INTEGER,
DIMENSION(:),
INTENT(IN) :: grid_offsets
258 INTEGER,
PARAMETER :: memory = 7
260 CHARACTER(LEN=60) :: csave, task
261 INTEGER :: evaluations
262 REAL(kind=dp),
DIMENSION(29) :: dsave
263 REAL(kind=dp),
DIMENSION(2*memory*SIZE(x)+5*SIZE(x&
)+11*memory**2+8*memory) :: wa
264 REAL(kind=dp) :: best_f, f, maximum_absolute_error
265 LOGICAL,
DIMENSION(4) :: lsave
266 LOGICAL :: evaluation_ok, have_best
267 INTEGER,
DIMENSION(SIZE(x)) :: bound_type
268 INTEGER,
DIMENSION(44) :: isave
269 INTEGER,
DIMENSION(3*SIZE(x)) :: iwa
270 REAL(kind=dp),
DIMENSION(SIZE(x)) :: best_x, g
272 cpassert(
SIZE(x) > 0)
273 cpassert(all(shape(lower) == shape(x)) .AND. all(shape(upper) == shape(x)))
274 cpassert(all(lower <= upper))
275 cpassert(accuracy > 0.0_dp .AND. max_evaluations > 0)
289 best_f = huge(best_f)
293 CALL setulb(
SIZE(x), memory, x, lower, upper, bound_type, f, g, &
294 0.0_dp, accuracy, wa, iwa, task, -1, csave, lsave, isave, dsave, -1.0_dp)
295 IF (task(1:2) ==
'FG')
THEN
296 IF (evaluations >= max_evaluations)
EXIT
297 CALL grid_objective(x, bs_env, clusters, grid_offsets, f, g, &
298 maximum_absolute_error, evaluation_ok)
299 evaluations = evaluations + 1
300 IF (.NOT. evaluation_ok)
EXIT
301 IF (.NOT. have_best .OR. f < best_f)
THEN
306 ELSE IF (task(1:5) ==
'NEW_X')
THEN
312 IF (have_best) x = best_x
313 END SUBROUTINE optimize_grid_coordinates
326 SUBROUTINE build_local_clusters(context, particle_set, cell, ao_size, ri_size, cutoff, &
328 TYPE(gw_3c_ctx_type),
INTENT(IN) :: context
329 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
330 TYPE(cell_type),
POINTER :: cell
331 INTEGER,
DIMENSION(:),
INTENT(IN) :: ao_size, ri_size
332 REAL(kind=dp),
INTENT(IN) :: cutoff
333 TYPE(mp_para_env_type),
POINTER :: para_env
334 TYPE(local_cluster_type),
ALLOCATABLE,
INTENT(OUT) :: clusters(:)
336 INTEGER :: center, ia, iatom, ja, jatom, ka, katom, &
337 n_ao, n_cluster, n_ri
338 INTEGER,
ALLOCATABLE :: ao_offset(:), atom_buffer(:), &
341 TYPE(gw_3c_ws_type) :: workspace
343 n_cluster = count([(mod(center - 1, para_env%num_pe) == para_env%mepos, &
344 center=1,
SIZE(particle_set))])
345 ALLOCATE (clusters(n_cluster), atom_buffer(
SIZE(particle_set)), &
346 ao_offset(
SIZE(particle_set)), ri_offset(
SIZE(particle_set)))
347 CALL gw_3c_ws_create(workspace, context)
349 DO center = 1,
SIZE(particle_set)
350 IF (mod(center - 1, para_env%num_pe) /= para_env%mepos) cycle
351 n_cluster = n_cluster + 1
353 DO iatom = 1,
SIZE(particle_set)
354 IF (sum(pbc(particle_set(iatom)%r - particle_set(center)%r, cell)**2) <= cutoff**2)
THEN
356 atom_buffer(ia) = iatom
359 ALLOCATE (clusters(n_cluster)%atoms(ia), source=atom_buffer(1:ia))
364 DO ia = 1,
SIZE(clusters(n_cluster)%atoms)
365 iatom = clusters(n_cluster)%atoms(ia)
366 ao_offset(iatom) = n_ao
367 ri_offset(iatom) = n_ri
368 n_ao = n_ao + ao_size(iatom)
369 n_ri = n_ri + ri_size(iatom)
371 ALLOCATE (clusters(n_cluster)%three_center(n_ao, n_ao, n_ri), source=0.0_dp)
372 DO ia = 1,
SIZE(clusters(n_cluster)%atoms)
373 iatom = clusters(n_cluster)%atoms(ia)
374 DO ka = 1,
SIZE(clusters(n_cluster)%atoms)
375 katom = clusters(n_cluster)%atoms(ka)
376 DO ja = 1,
SIZE(clusters(n_cluster)%atoms)
377 jatom = clusters(n_cluster)%atoms(ja)
378 CALL build_3c_integral_block_ctx( &
379 clusters(n_cluster)%three_center, context, workspace, &
380 atom_j=jatom, atom_k=katom, atom_i=iatom, &
381 j_offset=ao_offset(jatom), k_offset=ao_offset(katom), &
382 i_offset=ri_offset(iatom), screened=screened)
387 CALL gw_3c_ws_release(workspace)
388 END SUBROUTINE build_local_clusters
402 SUBROUTINE evaluate_local_cluster(cluster, grids, bs_env, particle_set, cell, &
403 value, gradient, maximum_absolute_error, successful)
404 TYPE(local_cluster_type),
INTENT(IN) :: cluster
405 TYPE(rirs_grid_type),
DIMENSION(:),
INTENT(IN) :: grids
406 TYPE(post_scf_bandstructure_type),
POINTER :: bs_env
407 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
408 TYPE(cell_type),
POINTER :: cell
409 REAL(kind=dp),
INTENT(OUT) ::
value
410 REAL(kind=dp),
ALLOCATABLE,
INTENT(OUT) :: gradient(:, :)
411 REAL(kind=dp),
INTENT(OUT) :: maximum_absolute_error
412 LOGICAL,
INTENT(OUT) :: successful
414 INTEGER :: ao_offset, ia, iatom, ikind, n_ao, &
415 n_atom_ao, n_grid, point_offset
416 REAL(kind=dp),
ALLOCATABLE :: dphi(:, :, :), phi(:, :), points(:, :)
417 TYPE(gto_basis_set_type),
POINTER :: basis
419 n_ao =
SIZE(cluster%three_center, 1)
421 DO ia = 1,
SIZE(cluster%atoms)
422 iatom = cluster%atoms(ia)
423 n_grid = n_grid +
SIZE(grids(iatom)%raw_points, 2)
425 ALLOCATE (points(3, n_grid), phi(n_grid, n_ao), &
426 dphi(3, n_grid, n_ao), gradient(3, n_grid))
430 DO ia = 1,
SIZE(cluster%atoms)
431 iatom = cluster%atoms(ia)
432 points(:, point_offset + 1:point_offset +
SIZE(grids(iatom)%raw_points, 2)) = &
433 spread(particle_set(iatom)%r, 2,
SIZE(grids(iatom)%raw_points, 2)) + &
434 grids(iatom)%raw_points
435 point_offset = point_offset +
SIZE(grids(iatom)%raw_points, 2)
438 DO ia = 1,
SIZE(cluster%atoms)
439 iatom = cluster%atoms(ia)
440 ikind = particle_set(iatom)%atomic_kind%kind_number
441 basis => bs_env%basis_set_AO(ikind)%gto_basis_set
442 n_atom_ao = basis%nsgf
443 CALL evaluate_ao_basis_on_points( &
444 phi(:, ao_offset + 1:ao_offset + n_atom_ao), points, basis, &
445 particle_set(iatom)%r, cell, &
446 dphi=dphi(:, :, ao_offset + 1:ao_offset + n_atom_ao))
447 ao_offset = ao_offset + n_atom_ao
449 CALL evaluate_rirs_grid_cluster(phi, dphi, cluster%three_center, bs_env%ri_rs%tikhonov, &
450 value, gradient, maximum_absolute_error, successful)
451 END SUBROUTINE evaluate_local_cluster
467 SUBROUTINE evaluate_rirs_grid_cluster(phi, dphi, three_center, tikhonov, value, gradient, &
468 maximum_absolute_error, successful)
469 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: phi
470 REAL(kind=dp),
DIMENSION(:, :, :),
INTENT(IN) :: dphi, three_center
471 REAL(kind=dp),
INTENT(IN) :: tikhonov
472 REAL(kind=dp),
INTENT(OUT) ::
value
473 REAL(kind=dp),
DIMENSION(:, :),
INTENT(OUT) :: gradient
474 REAL(kind=dp),
INTENT(OUT) :: maximum_absolute_error
475 LOGICAL,
INTENT(OUT) :: successful
477 CHARACTER(len=*),
PARAMETER :: routinen =
'evaluate_rirs_grid_cluster'
478 REAL(kind=dp),
PARAMETER :: jacobi_floor = 1.0e-16_dp
480 INTEGER :: alpha, handle, info, ipair, l, mu, n_ao, &
481 n_grid, n_pair, n_ri, nu, p
482 INTEGER,
ALLOCATABLE :: pair_mu(:), pair_nu(:)
483 REAL(kind=dp) :: absolute_error, column_norm2, d_a, &
484 denom, factor, projection, scale
485 REAL(kind=dp),
ALLOCATABLE :: a_matrix(:, :), a_scaled(:, :), b_matrix(:, :), &
486 derivative_a(:, :), derivative_scaled_a(:), gram(:, :), residual(:, :), rhs(:, :), &
487 scale_columns(:), y_matrix(:, :), yz_matrix(:, :), z_matrix(:, :)
489 CALL timeset(routinen, handle)
491 n_grid =
SIZE(phi, 1)
493 n_ri =
SIZE(three_center, 3)
494 n_pair = n_ao*(n_ao + 1)/2
496 cpassert(
SIZE(dphi, 1) == 3)
497 cpassert(
SIZE(dphi, 2) == n_grid)
498 cpassert(
SIZE(dphi, 3) == n_ao)
499 cpassert(
SIZE(three_center, 1) == n_ao)
500 cpassert(
SIZE(three_center, 2) == n_ao)
501 cpassert(
SIZE(gradient, 1) == 3)
502 cpassert(
SIZE(gradient, 2) == n_grid)
503 cpassert(tikhonov >= 0.0_dp)
507 maximum_absolute_error = huge(maximum_absolute_error)
509 IF (n_grid < 1 .OR. n_ri < 1)
THEN
510 CALL timestop(handle)
514 ALLOCATE (a_matrix(n_pair, n_grid), a_scaled(n_pair, n_grid), &
515 b_matrix(n_pair, n_ri), pair_mu(n_pair), pair_nu(n_pair), &
516 scale_columns(n_grid))
523 factor = sqrt(real(2 - merge(1, 0, mu == nu), dp))
525 a_matrix(ipair, l) = factor*phi(l, mu)*phi(l, nu)
528 b_matrix(ipair, p) = factor*three_center(mu, nu, p)
533 denom = sum(b_matrix*b_matrix)
534 IF (denom <= tiny(1.0_dp))
THEN
535 DEALLOCATE (a_matrix, a_scaled, b_matrix, pair_mu, pair_nu, scale_columns)
536 CALL timestop(handle)
542 column_norm2 = sum(a_matrix(:, l)*a_matrix(:, l))
543 scale_columns(l) = 1.0_dp/sqrt(max(column_norm2, jacobi_floor))
544 a_scaled(:, l) = scale_columns(l)*a_matrix(:, l)
546 ALLOCATE (gram(n_grid, n_grid), rhs(n_grid, n_ri), z_matrix(n_grid, n_ri))
547 CALL dgemm(
'T',
'N', n_grid, n_grid, n_pair, 1.0_dp, a_scaled, n_pair, &
548 a_scaled, n_pair, 0.0_dp, gram, n_grid)
550 gram(l, l) = gram(l, l) + tikhonov
552 CALL dgemm(
'T',
'N', n_grid, n_ri, n_pair, 1.0_dp, a_scaled, n_pair, &
553 b_matrix, n_pair, 0.0_dp, rhs, n_grid)
554 CALL dpotrf(
'L', n_grid, gram, n_grid, info)
556 DEALLOCATE (a_matrix, a_scaled, b_matrix, gram, pair_mu, pair_nu, rhs, &
557 scale_columns, z_matrix)
558 CALL timestop(handle)
562 CALL dpotrs(
'L', n_grid, n_ri, gram, n_grid, z_matrix, n_grid, info)
565 DEALLOCATE (a_matrix, a_scaled, b_matrix, gram, pair_mu, pair_nu, &
566 scale_columns, z_matrix)
567 CALL timestop(handle)
571 ALLOCATE (residual(n_pair, n_ri))
572 residual(:, :) = b_matrix
573 CALL dgemm(
'N',
'N', n_pair, n_ri, n_grid, -1.0_dp, a_scaled, n_pair, &
574 z_matrix, n_grid, 1.0_dp, residual, n_pair)
575 value = sum(residual*residual)/denom
580 ALLOCATE (y_matrix(n_grid, n_ri), derivative_a(n_pair, n_grid))
581 y_matrix(:, :) = z_matrix
582 CALL dpotrs(
'L', n_grid, n_ri, gram, n_grid, y_matrix, n_grid, info)
584 DEALLOCATE (a_matrix, a_scaled, b_matrix, derivative_a, gram, pair_mu, pair_nu, &
585 residual, scale_columns, y_matrix, z_matrix)
586 CALL timestop(handle)
589 CALL dgemm(
'N',
'T', n_pair, n_grid, n_ri, -2.0_dp/denom, residual, n_pair, &
590 z_matrix, n_grid, 0.0_dp, derivative_a, n_pair)
591 IF (tikhonov > 0.0_dp)
THEN
592 CALL dgemm(
'N',
'T', n_pair, n_grid, n_ri, -2.0_dp*tikhonov/denom, residual, n_pair, &
593 y_matrix, n_grid, 1.0_dp, derivative_a, n_pair)
594 ALLOCATE (yz_matrix(n_grid, n_grid))
595 CALL dgemm(
'N',
'T', n_grid, n_grid, n_ri, 1.0_dp, y_matrix, n_grid, &
596 z_matrix, n_grid, 0.0_dp, yz_matrix, n_grid)
597 CALL dgemm(
'N',
'N', n_pair, n_grid, n_grid, 2.0_dp*tikhonov/denom, a_scaled, n_pair, &
598 yz_matrix, n_grid, 1.0_dp, derivative_a, n_pair)
599 DEALLOCATE (yz_matrix)
602 ALLOCATE (derivative_scaled_a(n_pair))
604 scale = scale_columns(l)
605 column_norm2 = sum(a_matrix(:, l)*a_matrix(:, l))
610 factor = sqrt(real(2 - merge(1, 0, mu == nu), dp))
611 d_a = factor*(dphi(alpha, l, mu)*phi(l, nu) + &
612 phi(l, mu)*dphi(alpha, l, nu))
613 derivative_scaled_a(ipair) = scale*d_a
615 IF (column_norm2 > jacobi_floor)
THEN
616 projection = dot_product(a_matrix(:, l), derivative_scaled_a)/scale
617 derivative_scaled_a(:) = derivative_scaled_a - &
618 scale**3*a_matrix(:, l)*projection
620 gradient(alpha, l) = dot_product(derivative_a(:, l), derivative_scaled_a)
624 maximum_absolute_error = 0.0_dp
627 factor = sqrt(real(2 - merge(1, 0, pair_mu(ipair) == pair_nu(ipair)), dp))
628 absolute_error = abs(residual(ipair, p))/factor
629 maximum_absolute_error = max(maximum_absolute_error, absolute_error)
634 DEALLOCATE (a_matrix, a_scaled, b_matrix, derivative_a, derivative_scaled_a, gram, &
635 pair_mu, pair_nu, residual, scale_columns, y_matrix, z_matrix)
636 CALL timestop(handle)
637 END SUBROUTINE evaluate_rirs_grid_cluster
647 SUBROUTINE accumulate_atom_gradient(atoms, grids, grid_offsets, physical_gradient, gradient)
648 INTEGER,
DIMENSION(:),
INTENT(IN) :: atoms
649 TYPE(rirs_grid_type),
DIMENSION(:),
INTENT(IN) :: grids
650 INTEGER,
DIMENSION(:),
INTENT(IN) :: grid_offsets
651 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: physical_gradient
652 REAL(kind=dp),
DIMENSION(:),
INTENT(INOUT) :: gradient
654 INTEGER :: alpha, ia, iatom, l, point_offset
657 DO ia = 1,
SIZE(atoms)
659 DO l = 1,
SIZE(grids(iatom)%raw_points, 2)
661 gradient(grid_offsets(iatom) + 3*(l - 1) + alpha) = &
662 gradient(grid_offsets(iatom) + 3*(l - 1) + alpha) + &
663 physical_gradient(alpha, point_offset + l)
666 point_offset = point_offset +
SIZE(grids(iatom)%raw_points, 2)
668 END SUBROUTINE accumulate_atom_gradient
676 SUBROUTINE pack_atom_grids(grids, grid_offsets, coordinates)
677 TYPE(rirs_grid_type),
DIMENSION(:),
INTENT(IN) :: grids
678 INTEGER,
DIMENSION(:),
INTENT(IN) :: grid_offsets
679 REAL(kind=dp),
DIMENSION(:),
INTENT(OUT) :: coordinates
681 INTEGER :: iatom, n_coordinate
683 cpassert(
SIZE(grid_offsets) ==
SIZE(grids))
684 DO iatom = 1,
SIZE(grids)
685 n_coordinate =
SIZE(grids(iatom)%raw_points)
686 coordinates(grid_offsets(iatom) + 1:grid_offsets(iatom) + n_coordinate) = &
687 reshape(grids(iatom)%raw_points, [n_coordinate])
689 END SUBROUTINE pack_atom_grids
697 SUBROUTINE unpack_atom_grids(coordinates, grids, grid_offsets)
698 REAL(kind=dp),
DIMENSION(:),
INTENT(IN) :: coordinates
699 TYPE(rirs_grid_type),
DIMENSION(:),
INTENT(INOUT) :: grids
700 INTEGER,
DIMENSION(:),
INTENT(IN) :: grid_offsets
702 INTEGER :: iatom, n_coordinate
704 cpassert(
SIZE(grid_offsets) ==
SIZE(grids))
705 DO iatom = 1,
SIZE(grids)
706 n_coordinate =
SIZE(grids(iatom)%raw_points)
707 grids(iatom)%raw_points(:, :) = reshape( &
708 coordinates(grid_offsets(iatom) + 1:grid_offsets(iatom) + n_coordinate), &
709 shape(grids(iatom)%raw_points))
711 END SUBROUTINE unpack_atom_grids
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Handles all functions related to the CELL.
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
integer, parameter, public use_perd_none
LBFGS-B routine (version 3.0, April 25, 2011).
subroutine, public setulb(n, m, x, lower_bound, upper_bound, nbd, f, g, factr, pgtol, wa, iwa, task, iprint, csave, lsave, isave, dsave, trust_radius, spgr, iwunit)
This subroutine partitions the working arrays wa and iwa, and then uses the limited memory BFGS metho...
Utility method to build 3-center integrals for small cell GW.
subroutine, public build_3c_integral_block_ctx(int_3c, ctx, ws, atom_j, atom_k, atom_i, cell_j, cell_k, cell_i, j_offset, k_offset, i_offset, screened)
Computes the 3c integral block (mu(atom_j) nu(atom_k) | P(atom_i)) for ONE atom triple,...
subroutine, public gw_3c_ws_create(ws, ctx)
Creates a per-thread 3c workspace: libint object + LIBXSMM contraction buffers.
subroutine, public gw_3c_ws_release(ws)
Releases a per-thread 3c workspace.
subroutine, public gw_3c_ctx_release(ctx)
Releases the shared 3c-integral context.
subroutine, public gw_3c_ctx_create(ctx, qs_env, potential_parameter, basis_j, basis_k, basis_i)
Builds the shared 3c-integral context: screening radii, basis maxima, contracted sphi tables,...
Local-environment optimizer for atom-centred real-space RI grids.
subroutine, public optimize_ri_rs_grid(qs_env, bs_env)
Optimize the selected RI-RS grids stored in a GW band-structure environment.
Defines the basic variable types.
integer, parameter, public dp
2- and 3-center electron repulsion integral routines based on libint2 Currently available operators: ...
Interface to the message passing library MPI.
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public angstrom
Shared RI-RS grid I/O and contracted-Gaussian evaluation utilities.
subroutine, public evaluate_ao_basis_on_points(phi, grid_points, basis, source_position, cell, dphi, cutoff_squared)
Evaluate one explicitly supplied contracted Gaussian basis on Cartesian points.
Type defining parameters related to the simulation cell.
Shared read-only context for repeated 3-center integral block builds: screening parameters,...
Per-thread workspace for 3-center integral block builds: libint object + contraction buffers....
stores all the informations relevant to an mpi environment