37#include "./base/base_uses.f90"
44 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'ri_rs_grid_optimization'
46 TYPE,
PRIVATE :: local_cluster_3c_integrals_type
47 INTEGER,
ALLOCATABLE :: atom_indices(:)
48 REAL(KIND=
dp),
ALLOCATABLE :: int_3c(:, :, :)
49 END TYPE local_cluster_3c_integrals_type
60 CHARACTER(len=*),
PARAMETER :: routinen =
'optimize_ri_rs_grid'
63 TYPE(local_cluster_3c_integrals_type),
ALLOCATABLE :: cluster_3c_int(:)
65 CALL timeset(routinen, handle)
68 CALL validate_ri_rs_grid_optimization_input(bs_env)
74 CALL prepare_ri_rs_grid_optimization(bs_env)
77 CALL build_cluster_3c_int(bs_env, cluster_3c_int)
81 CALL optimize_grid_coordinates(bs_env, cluster_3c_int)
91 SUBROUTINE validate_ri_rs_grid_optimization_input(bs_env)
94 INTEGER :: iatom, ikind
96 cpassert(
ASSOCIATED(bs_env%ri_rs%cell))
97 cpassert(
ASSOCIATED(bs_env%ri_rs%particle_set))
98 cpassert(
ASSOCIATED(bs_env%para_env))
99 cpassert(
ALLOCATED(bs_env%basis_set_AO))
100 cpassert(
ALLOCATED(bs_env%basis_set_RI))
101 cpassert(
ALLOCATED(bs_env%sizes_AO))
102 cpassert(
SIZE(bs_env%ri_rs%particle_set) == bs_env%n_atom)
103 cpassert(
SIZE(bs_env%sizes_AO) == bs_env%n_atom)
104 cpassert(
SIZE(bs_env%basis_set_AO) ==
SIZE(bs_env%basis_set_RI))
106 IF (bs_env%ri_rs%grid_opt%rs_ao_ratio <= 0.0_dp)
THEN
107 cpabort(
"GRID_OPTIMIZATION%RS_AO_RATIO must be positive")
109 IF (bs_env%ri_rs%grid_opt%cutoff_atomic_cluster <= 0.0_dp)
THEN
110 cpabort(
"GRID_OPTIMIZATION%CUTOFF_ATOMIC_CLUSTER must be positive")
112 IF (bs_env%ri_rs%grid_opt%max_iter < 1)
THEN
113 cpabort(
"GRID_OPTIMIZATION%MAX_ITER must be positive")
115 IF (bs_env%ri_rs%tikhonov < 0.0_dp)
THEN
116 cpabort(
"RI_RS%TIKHONOV must not be negative")
119 DO iatom = 1, bs_env%n_atom
120 ikind = bs_env%ri_rs%particle_set(iatom)%atomic_kind%kind_number
121 cpassert(ikind >= 1 .AND. ikind <=
SIZE(bs_env%basis_set_AO))
122 cpassert(
ASSOCIATED(bs_env%basis_set_AO(ikind)%gto_basis_set))
123 cpassert(
ASSOCIATED(bs_env%basis_set_RI(ikind)%gto_basis_set))
124 IF (bs_env%sizes_AO(iatom) < 1 .OR. &
125 bs_env%basis_set_RI(ikind)%gto_basis_set%nsgf < 1)
THEN
126 cpabort(
"Every atom in GRID_OPTIMIZATION needs ORB and RI_AUX functions")
129 END SUBROUTINE validate_ri_rs_grid_optimization_input
135 SUBROUTINE prepare_ri_rs_grid_optimization(bs_env)
138 INTEGER :: iatom, unit_nr
140 cpassert(
ALLOCATED(bs_env%ri_rs%atomic_grids))
141 cpassert(
SIZE(bs_env%ri_rs%atomic_grids) == bs_env%n_atom)
143 DO iatom = 1, bs_env%n_atom
144 cpassert(
ALLOCATED(bs_env%ri_rs%atomic_grids(iatom)%raw_points))
145 cpassert(
SIZE(bs_env%ri_rs%atomic_grids(iatom)%raw_points, 1) == 3)
146 cpassert(
SIZE(bs_env%ri_rs%atomic_grids(iatom)%raw_points, 2) > 0)
149 unit_nr = bs_env%unit_nr
150 IF (unit_nr > 0)
THEN
151 WRITE (unit_nr,
'(T2,A)')
'Started RI-RS grid optimization'
154 END SUBROUTINE prepare_ri_rs_grid_optimization
168 SUBROUTINE grid_objective(grid_coordinates, atom_coordinate_offsets, bs_env, cluster_3c_int, &
169 fit_memory_budget, normalized_error, coordinate_gradient, &
170 max_abs_error, fit_successful)
171 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: grid_coordinates
172 INTEGER,
DIMENSION(:),
INTENT(IN) :: atom_coordinate_offsets
174 TYPE(local_cluster_3c_integrals_type), &
175 DIMENSION(:),
INTENT(IN) :: cluster_3c_int
176 REAL(kind=
dp),
INTENT(IN) :: fit_memory_budget
177 REAL(kind=
dp),
INTENT(OUT) :: normalized_error
178 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT),
OPTIONAL :: coordinate_gradient
179 REAL(kind=
dp),
INTENT(OUT) :: max_abs_error
180 LOGICAL,
INTENT(OUT) :: fit_successful
182 INTEGER :: evaluated_cluster_count, icluster, &
184 LOGICAL :: cluster_fit_successful
185 REAL(kind=
dp) :: cluster_max_abs_error, &
186 cluster_normalized_error
187 REAL(kind=
dp),
ALLOCATABLE :: cluster_coordinate_gradient(:, :)
190 para_env => bs_env%para_env
191 IF (
PRESENT(coordinate_gradient))
THEN
192 cpassert(
SIZE(coordinate_gradient) ==
SIZE(grid_coordinates))
193 coordinate_gradient(:) = 0.0_dp
195 CALL unpack_lbfgs_grid_coordinates(grid_coordinates, atom_coordinate_offsets, &
196 bs_env%ri_rs%atomic_grids)
197 normalized_error = 0.0_dp
198 evaluated_cluster_count = 0
199 max_abs_error = 0.0_dp
200 fit_successful = .true.
201 DO icluster = 1,
SIZE(cluster_3c_int)
202 IF (
PRESENT(coordinate_gradient))
THEN
203 CALL evaluate_local_cluster(cluster_3c_int(icluster), bs_env, fit_memory_budget, cluster_normalized_error, &
204 cluster_max_abs_error, cluster_fit_successful, cluster_coordinate_gradient)
206 CALL evaluate_local_cluster(cluster_3c_int(icluster), bs_env, fit_memory_budget, cluster_normalized_error, &
207 cluster_max_abs_error, cluster_fit_successful)
209 IF (.NOT. cluster_fit_successful)
THEN
210 fit_successful = .false.
213 normalized_error = normalized_error + cluster_normalized_error
214 IF (
PRESENT(coordinate_gradient))
THEN
215 CALL accumulate_atom_gradient(cluster_3c_int(icluster)%atom_indices, &
216 bs_env%ri_rs%atomic_grids, &
217 atom_coordinate_offsets, cluster_coordinate_gradient, &
219 DEALLOCATE (cluster_coordinate_gradient)
221 evaluated_cluster_count = evaluated_cluster_count + 1
223 max(max_abs_error, cluster_max_abs_error)
225 successful_ranks = merge(1, 0, fit_successful)
226 CALL para_env%sum(normalized_error)
227 IF (
PRESENT(coordinate_gradient))
CALL para_env%sum(coordinate_gradient)
228 CALL para_env%sum(evaluated_cluster_count)
229 CALL para_env%sum(successful_ranks)
230 CALL para_env%max(max_abs_error)
231 fit_successful = evaluated_cluster_count == bs_env%n_atom .AND. &
232 successful_ranks == para_env%num_pe
233 IF (.NOT. fit_successful)
THEN
234 normalized_error = huge(normalized_error)
235 IF (
PRESENT(coordinate_gradient)) coordinate_gradient(:) = 0.0_dp
239 normalized_error = normalized_error/real(bs_env%n_atom,
dp)
240 IF (
PRESENT(coordinate_gradient)) coordinate_gradient(:) = coordinate_gradient/real(bs_env%n_atom,
dp)
241 END SUBROUTINE grid_objective
248 SUBROUTINE optimize_grid_coordinates(bs_env, cluster_3c_int)
250 TYPE(local_cluster_3c_integrals_type), &
251 DIMENSION(:),
INTENT(IN) :: cluster_3c_int
253 INTEGER,
PARAMETER :: lbfgs_history = 7
254 REAL(kind=
dp),
PARAMETER :: lbfgs_factr = 0.0_dp, &
255 lbfgs_pgtol = 1.0e-9_dp, &
258 CHARACTER(LEN=60) :: line_search_state, optimizer_task
259 INTEGER :: evaluation_count, handle, iatom, &
260 molecular_outside, npoints, unit_nr
261 INTEGER,
ALLOCATABLE :: atom_coordinate_offsets(:), &
262 bound_types(:), integer_workspace(:)
263 INTEGER,
DIMENSION(44) :: integer_state
264 LOGICAL :: evaluation_successful, fit_successful, &
266 LOGICAL,
ALLOCATABLE :: inside(:)
267 LOGICAL,
DIMENSION(4) :: logical_state
268 REAL(kind=
dp) :: best_normalized_error, &
269 fit_memory_budget, max_abs_error, &
270 mem_avail_gb, normalized_error, &
272 REAL(kind=
dp),
ALLOCATABLE :: best_grid_coordinates(:), coordinate_gradient(:), &
273 grid_coordinates(:), lower_bounds(:), points(:, :), upper_bounds(:), workspace(:)
274 REAL(kind=
dp),
DIMENSION(29) :: real_state
276 CALL timeset(
"rirs_grid_LBFGS", handle)
279 CALL pack_lbfgs_grid_coordinates(bs_env%ri_rs%atomic_grids, grid_coordinates, &
280 atom_coordinate_offsets)
281 cpassert(
SIZE(grid_coordinates) > 0)
283 ALLOCATE (best_grid_coordinates(
SIZE(grid_coordinates)), &
284 coordinate_gradient(
SIZE(grid_coordinates)), &
285 lower_bounds(
SIZE(grid_coordinates)), &
286 upper_bounds(
SIZE(grid_coordinates)), &
287 bound_types(
SIZE(grid_coordinates)), &
288 integer_workspace(3*
SIZE(grid_coordinates)), &
289 workspace(2*lbfgs_history*
SIZE(grid_coordinates) + &
290 5*
SIZE(grid_coordinates) + 11*lbfgs_history**2 + 8*lbfgs_history))
292 lower_bounds = 0.0_dp
293 upper_bounds = 0.0_dp
295 optimizer_task =
'START'
296 line_search_state =
''
297 normalized_error = huge(normalized_error)
298 coordinate_gradient = 0.0_dp
300 integer_workspace = 0
301 logical_state = .false.
306 best_normalized_error = huge(best_normalized_error)
307 best_grid_coordinates(:) = grid_coordinates
315 fit_memory_budget = mem_safety*mem_avail_gb*1.0e9_dp
316 IF (mem_avail_gb <= 0.0_dp .AND. bs_env%unit_nr > 0)
THEN
317 cpwarn(
"RI-RS grid optimization: no meminfo; streaming one RI column")
321 CALL setulb(
SIZE(grid_coordinates), lbfgs_history, grid_coordinates, &
322 lower_bounds, upper_bounds, bound_types, &
323 normalized_error, coordinate_gradient, lbfgs_factr, lbfgs_pgtol, &
324 workspace, integer_workspace, optimizer_task, -1, line_search_state, &
325 logical_state, integer_state, real_state, -1.0_dp)
326 IF (optimizer_task(1:2) ==
'FG')
THEN
327 IF (evaluation_count >= bs_env%ri_rs%grid_opt%max_iter)
EXIT
328 CALL grid_objective(grid_coordinates, atom_coordinate_offsets, bs_env, cluster_3c_int, &
329 fit_memory_budget, normalized_error, coordinate_gradient, &
330 max_abs_error, evaluation_successful)
331 evaluation_count = evaluation_count + 1
332 IF (.NOT. evaluation_successful)
EXIT
333 IF (evaluation_count == 1 .AND. bs_env%unit_nr > 0)
THEN
334 WRITE (bs_env%unit_nr,
'(T2,A,T61,ES20.12)') &
335 'RI-RS grid initial normalized error', normalized_error
338 IF (.NOT. have_best .OR. normalized_error < best_normalized_error)
THEN
340 best_normalized_error = normalized_error
341 best_grid_coordinates(:) = grid_coordinates
343 ELSE IF (optimizer_task(1:5) ==
'NEW_X')
THEN
349 IF (.NOT. have_best) cpabort(
"RI-RS grid optimization produced no regularized fit")
350 grid_coordinates(:) = best_grid_coordinates
353 CALL grid_objective(grid_coordinates, atom_coordinate_offsets, bs_env, cluster_3c_int, &
354 fit_memory_budget, normalized_error, max_abs_error=max_abs_error, fit_successful=fit_successful)
356 IF (.NOT. fit_successful) cpabort(
"RI-RS grid optimization produced no regularized fit")
358 DO iatom = 1,
SIZE(bs_env%ri_rs%atomic_grids)
359 bs_env%ri_rs%atomic_grids(iatom)%npts = &
360 SIZE(bs_env%ri_rs%atomic_grids(iatom)%raw_points, 2)
362 bs_env%ri_rs%Z_lP_exists = .false.
364 unit_nr = bs_env%unit_nr
365 IF (unit_nr > 0)
THEN
367 molecular_outside = 0
368 DO iatom = 1,
SIZE(bs_env%ri_rs%atomic_grids)
369 ALLOCATE (points(3, bs_env%ri_rs%atomic_grids(iatom)%npts), &
370 inside(bs_env%ri_rs%atomic_grids(iatom)%npts))
371 points(:, :) = bs_env%ri_rs%atomic_grids(iatom)%raw_points
373 molecular_outside = molecular_outside + count(.NOT. inside)
374 npoints = npoints +
SIZE(inside)
375 DEALLOCATE (points, inside)
377 WRITE (unit_nr,
'(T2,A,T69,F10.1,A)') &
378 'RI-RS grid optimization completed, execution time:',
m_walltime() - start_time,
' s'
379 WRITE (unit_nr,
'(T2,A,T72,ES9.1)')
'Normalized 3C error:', normalized_error
380 WRITE (unit_nr,
'(T2,A,T72,ES9.1)')
'Maximum absolute 3C error:', max_abs_error
381 WRITE (unit_nr,
'(T2,A,T60,I9,A,I9)') &
382 'Optimized points outside molecular Voronoi cells:', molecular_outside,
' / ', npoints
385 CALL timestop(handle)
386 END SUBROUTINE optimize_grid_coordinates
393 SUBROUTINE build_cluster_3c_int(bs_env, cluster_3c_int)
395 TYPE(local_cluster_3c_integrals_type), &
396 ALLOCATABLE,
INTENT(OUT) :: cluster_3c_int(:)
398 INTEGER :: handle, i_cluster_atom_j, i_cluster_atom_k, i_cluster_atom_p, iatom, iatom_j, &
399 iatom_k, iatom_p, icenter_atom, icluster_atom, ikind, ilocal_cluster, ip, &
400 n_local_clusters, nao_cluster, nri_cluster, nri_nonzero
401 INTEGER,
ALLOCATABLE :: ao_offset(:), ri_offset(:), &
404 REAL(kind=
dp) :: cluster_radius
405 REAL(kind=
dp),
ALLOCATABLE :: int_3c_nonzero(:, :, :)
412 CALL timeset(
"rirs_grid_build_clusters", handle)
414 cell => bs_env%ri_rs%cell
415 para_env => bs_env%para_env
416 particle_set => bs_env%ri_rs%particle_set
417 cluster_radius = bs_env%ri_rs%grid_opt%cutoff_atomic_cluster
418 ALLOCATE (sizes_ref_ri(bs_env%n_atom))
419 DO iatom = 1, bs_env%n_atom
420 ikind = particle_set(iatom)%atomic_kind%kind_number
421 sizes_ref_ri(iatom) = bs_env%basis_set_RI(ikind)%gto_basis_set%nsgf
423 n_local_clusters = count([(mod(icenter_atom - 1, para_env%num_pe) == para_env%mepos, &
424 icenter_atom=1, bs_env%n_atom)])
425 ALLOCATE (cluster_3c_int(n_local_clusters), &
426 ao_offset(bs_env%n_atom), ri_offset(bs_env%n_atom))
428 basis_j=bs_env%basis_set_AO, basis_k=bs_env%basis_set_AO, &
429 basis_i=bs_env%basis_set_RI)
432 DO icenter_atom = 1, bs_env%n_atom
433 IF (mod(icenter_atom - 1, para_env%num_pe) /= para_env%mepos) cycle
434 ilocal_cluster = ilocal_cluster + 1
436 cluster_3c_int(ilocal_cluster)%atom_indices)
441 DO icluster_atom = 1,
SIZE(cluster_3c_int(ilocal_cluster)%atom_indices)
442 iatom = cluster_3c_int(ilocal_cluster)%atom_indices(icluster_atom)
443 ao_offset(iatom) = nao_cluster
444 ri_offset(iatom) = nri_cluster
445 nao_cluster = nao_cluster + bs_env%sizes_AO(iatom)
446 nri_cluster = nri_cluster + sizes_ref_ri(iatom)
448 ALLOCATE (cluster_3c_int(ilocal_cluster)%Int_3c(nao_cluster, nao_cluster, nri_cluster), &
450 DO i_cluster_atom_p = 1,
SIZE(cluster_3c_int(ilocal_cluster)%atom_indices)
451 iatom_p = cluster_3c_int(ilocal_cluster)%atom_indices(i_cluster_atom_p)
452 DO i_cluster_atom_k = 1,
SIZE(cluster_3c_int(ilocal_cluster)%atom_indices)
453 iatom_k = cluster_3c_int(ilocal_cluster)%atom_indices(i_cluster_atom_k)
456 DO i_cluster_atom_j = 1, i_cluster_atom_k
457 iatom_j = cluster_3c_int(ilocal_cluster)%atom_indices(i_cluster_atom_j)
459 integral_context, workspace, &
460 atom_j=iatom_j, atom_k=iatom_k, atom_i=iatom_p, &
461 j_offset=ao_offset(iatom_j), &
462 k_offset=ao_offset(iatom_k), &
463 i_offset=ri_offset(iatom_p), screened=screened)
468 nri_nonzero = count([(any(cluster_3c_int(ilocal_cluster)%Int_3c(:, :, ip) /= 0.0_dp), &
470 IF (nri_nonzero < nri_cluster)
THEN
471 ALLOCATE (int_3c_nonzero(nao_cluster, nao_cluster, nri_nonzero))
473 DO ip = 1, nri_cluster
474 IF (.NOT. any(cluster_3c_int(ilocal_cluster)%Int_3c(:, :, ip) /= 0.0_dp)) cycle
475 nri_nonzero = nri_nonzero + 1
476 int_3c_nonzero(:, :, nri_nonzero) = cluster_3c_int(ilocal_cluster)%Int_3c(:, :, ip)
478 CALL move_alloc(int_3c_nonzero, cluster_3c_int(ilocal_cluster)%Int_3c)
483 CALL timestop(handle)
484 END SUBROUTINE build_cluster_3c_int
496 SUBROUTINE evaluate_local_cluster(cluster_3c_int, bs_env, fit_memory_budget, normalized_error, max_abs_error, &
497 fit_successful, coordinate_gradient)
498 TYPE(local_cluster_3c_integrals_type),
INTENT(IN) :: cluster_3c_int
500 REAL(kind=
dp),
INTENT(IN) :: fit_memory_budget
501 REAL(kind=
dp),
INTENT(OUT) :: normalized_error, max_abs_error
502 LOGICAL,
INTENT(OUT) :: fit_successful
503 REAL(kind=
dp),
ALLOCATABLE,
INTENT(OUT),
OPTIONAL :: coordinate_gradient(:, :)
505 INTEGER :: ao_offset, grid_point_offset, iatom, &
506 icartesian, icluster_atom, igrid, &
507 ikind, n_grid_points, nao, nao_atom
508 REAL(kind=
dp) :: evaluation_budget
509 REAL(kind=
dp),
ALLOCATABLE :: ao_gradient(:, :), &
510 dphi_alpha_l_mu(:, :, :), &
511 grid_points(:, :), phi_l_mu(:, :)
516 cell => bs_env%ri_rs%cell
517 particle_set => bs_env%ri_rs%particle_set
518 nao =
SIZE(cluster_3c_int%Int_3c, 1)
520 DO icluster_atom = 1,
SIZE(cluster_3c_int%atom_indices)
521 iatom = cluster_3c_int%atom_indices(icluster_atom)
522 n_grid_points = n_grid_points +
SIZE(bs_env%ri_rs%atomic_grids(iatom)%raw_points, 2)
524 evaluation_budget = 0.0_dp
525 IF (
PRESENT(coordinate_gradient) .AND. fit_memory_budget > 0.0_dp)
THEN
527 evaluation_budget = fit_memory_budget - &
528 8.0_dp*real(n_grid_points,
dp)*(5.0_dp*real(nao,
dp) + 6.0_dp)
529 IF (evaluation_budget <= 0.0_dp)
THEN
530 cpabort(
"RI-RS cluster AO workspace exceeds memory budget")
533 ALLOCATE (grid_points(3, n_grid_points), phi_l_mu(n_grid_points, nao))
534 IF (
PRESENT(coordinate_gradient))
THEN
535 ALLOCATE (dphi_alpha_l_mu(3, n_grid_points, nao), ao_gradient(n_grid_points, nao), &
536 coordinate_gradient(3, n_grid_points))
537 dphi_alpha_l_mu = 0.0_dp
538 coordinate_gradient(:, :) = 0.0_dp
541 grid_point_offset = 0
542 DO icluster_atom = 1,
SIZE(cluster_3c_int%atom_indices)
543 iatom = cluster_3c_int%atom_indices(icluster_atom)
544 grid_points(:, grid_point_offset + 1:grid_point_offset + &
545 SIZE(bs_env%ri_rs%atomic_grids(iatom)%raw_points, 2)) = &
546 spread(particle_set(iatom)%r, 2, &
547 SIZE(bs_env%ri_rs%atomic_grids(iatom)%raw_points, 2)) + &
548 bs_env%ri_rs%atomic_grids(iatom)%raw_points
549 grid_point_offset = grid_point_offset +
SIZE(bs_env%ri_rs%atomic_grids(iatom)%raw_points, 2)
552 DO icluster_atom = 1,
SIZE(cluster_3c_int%atom_indices)
553 iatom = cluster_3c_int%atom_indices(icluster_atom)
554 ikind = particle_set(iatom)%atomic_kind%kind_number
555 ao_basis => bs_env%basis_set_AO(ikind)%gto_basis_set
556 nao_atom = ao_basis%nsgf
557 IF (
PRESENT(coordinate_gradient))
THEN
559 grid_points, ao_basis, particle_set(iatom)%r, cell, &
560 dphi=dphi_alpha_l_mu(:, :, ao_offset + 1:ao_offset + nao_atom))
563 grid_points, ao_basis, particle_set(iatom)%r, cell)
565 ao_offset = ao_offset + nao_atom
567 max_abs_error = 0.0_dp
568 IF (
PRESENT(coordinate_gradient))
THEN
570 normalized_error, fit_successful, ao_gradient=ao_gradient, &
571 workspace_budget_bytes=evaluation_budget)
572 IF (.NOT. fit_successful)
RETURN
573 DO igrid = 1, n_grid_points
575 coordinate_gradient(icartesian, igrid) = &
576 dot_product(ao_gradient(igrid, :), dphi_alpha_l_mu(icartesian, igrid, :))
581 normalized_error, fit_successful, max_abs_error=max_abs_error)
583 END SUBROUTINE evaluate_local_cluster
593 SUBROUTINE accumulate_atom_gradient(cluster_atoms, grids, atom_coordinate_offsets, &
594 cluster_coordinate_gradient, coordinate_gradient)
595 INTEGER,
DIMENSION(:),
INTENT(IN) :: cluster_atoms
597 INTEGER,
DIMENSION(:),
INTENT(IN) :: atom_coordinate_offsets
598 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: cluster_coordinate_gradient
599 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: coordinate_gradient
601 INTEGER :: grid_point_offset, iatom, icartesian, &
602 icluster_atom, igrid_point
604 grid_point_offset = 0
605 DO icluster_atom = 1,
SIZE(cluster_atoms)
606 iatom = cluster_atoms(icluster_atom)
607 DO igrid_point = 1,
SIZE(grids(iatom)%raw_points, 2)
609 coordinate_gradient(atom_coordinate_offsets(iatom) + 3*(igrid_point - 1) + icartesian) = &
610 coordinate_gradient(atom_coordinate_offsets(iatom) + 3*(igrid_point - 1) + icartesian) + &
611 cluster_coordinate_gradient(icartesian, grid_point_offset + igrid_point)
614 grid_point_offset = grid_point_offset +
SIZE(grids(iatom)%raw_points, 2)
616 END SUBROUTINE accumulate_atom_gradient
627 SUBROUTINE pack_lbfgs_grid_coordinates(grids, grid_coordinates, atom_coordinate_offsets)
629 REAL(kind=
dp),
ALLOCATABLE,
INTENT(OUT) :: grid_coordinates(:)
630 INTEGER,
ALLOCATABLE,
INTENT(OUT) :: atom_coordinate_offsets(:)
632 INTEGER :: atom_coordinate_count, iatom, &
635 ALLOCATE (atom_coordinate_offsets(
SIZE(grids)))
636 n_grid_coordinates = 0
637 DO iatom = 1,
SIZE(grids)
638 atom_coordinate_offsets(iatom) = n_grid_coordinates
639 n_grid_coordinates = n_grid_coordinates +
SIZE(grids(iatom)%raw_points)
641 ALLOCATE (grid_coordinates(n_grid_coordinates))
643 DO iatom = 1,
SIZE(grids)
644 atom_coordinate_count =
SIZE(grids(iatom)%raw_points)
645 grid_coordinates(atom_coordinate_offsets(iatom) + 1: &
646 atom_coordinate_offsets(iatom) + atom_coordinate_count) = &
647 reshape(grids(iatom)%raw_points, [atom_coordinate_count])
649 END SUBROUTINE pack_lbfgs_grid_coordinates
657 SUBROUTINE unpack_lbfgs_grid_coordinates(grid_coordinates, atom_coordinate_offsets, grids)
658 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: grid_coordinates
659 INTEGER,
DIMENSION(:),
INTENT(IN) :: atom_coordinate_offsets
662 INTEGER :: atom_coordinate_count, iatom
664 cpassert(
SIZE(atom_coordinate_offsets) ==
SIZE(grids))
665 DO iatom = 1,
SIZE(grids)
666 atom_coordinate_count =
SIZE(grids(iatom)%raw_points)
667 grids(iatom)%raw_points(:, :) = reshape( &
668 grid_coordinates(atom_coordinate_offsets(iatom) + 1: &
669 atom_coordinate_offsets(iatom) + &
670 atom_coordinate_count), &
671 shape(grids(iatom)%raw_points))
673 END SUBROUTINE unpack_lbfgs_grid_coordinates
Handles all functions related to the CELL.
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 gw_3c_ws_create(ws, ctx)
Creates a per-thread 3c workspace: libint object + LIBXSMM contraction buffers.
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_ctx_release(ctx)
Releases the shared 3c-integral context.
subroutine, public gw_3c_ws_release(ws)
Releases a per-thread 3c workspace.
subroutine, public gw_3c_ctx_create(ctx, bs_env, potential_parameter, basis_j, basis_k, basis_i)
Build the shared 3c-integral context from the band-structure environment and explicitly supplied pote...
Defines the basic variable types.
integer, parameter, public dp
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Interface to the message passing library MPI.
subroutine, public mp_mem_avail_per_rank_gb(comm, mem_avail_gb)
Memory that is currently free on the node, per MPI rank of that node, in GB.
Define the data structure for the particle information.
Shared numerical operations for computing the RI-RS matrix Z_lP.
subroutine, public evaluate_ri_rs_fit(phi, int_3c, tikhonov, normalized_error, fit_successful, ao_gradient, max_abs_error, workspace_budget_bytes)
Evaluate the normalized cluster residual and its exact derivative in AO space.
Initialize atom-owned RI-RS grids by Cholesky selection from Lebedev grids.
subroutine, public initialize_ri_rs_grid(bs_env)
Construct the initial RI-RS grid of every atom.
Optimize automatically initialized atom-centred RI-RS grids.
subroutine, public optimize_ri_rs_grid(bs_env)
Initialize Lebedev grids and subsequently optimize their grid-point coordinates.
Shared real-space resolution-of-identity grid and matrix data.
Geometry and AO evaluation for real-space resolution of the identity.
subroutine, public evaluate_ao_basis_on_points(phi, grid_points, basis, source_position, cell, dphi, cutoff_squared, periodic_images)
Evaluate one explicitly supplied contracted Gaussian basis on Cartesian points.
subroutine, public filter_grid_to_voronoi(points, icenter_atom, particle_set, mask, atom_indices)
Retain source-grid points inside the Voronoi volume of one atom.
subroutine, public get_rirs_cluster_atoms(particle_set, cell, icenter_atom, radius, atom_indices)
Form C_A from nuclei within the specified radius, in global atom order.
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