23 dbcsr_type_no_symmetry
42#include "./base/base_uses.f90"
80 PRIVATE :: qs_ot_p2m_diag
81 PRIVATE :: qs_ot_p2m_diag_complex
82 PRIVATE :: qs_ot_complex_multiply
84 PRIVATE :: qs_ot_ref_poly
85 PRIVATE :: qs_ot_ref_chol
86 PRIVATE :: qs_ot_ref_lwdn
87 PRIVATE :: qs_ot_ref_decide
88 PRIVATE :: qs_ot_ref_update
89 PRIVATE :: qs_ot_refine
90 PRIVATE :: qs_ot_on_the_fly_localize
92 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_ot'
102 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: rotation_generator
103 REAL(kind=
dp) :: norm
105 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: eigenvectors
107 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues
109 n =
SIZE(rotation_generator, 1)
110 cpassert(
SIZE(rotation_generator, 2) == n)
113 ALLOCATE (eigenvectors(n, n), eigenvalues(n))
114 CALL diag_complex(cmplx(0.0_dp, 1.0_dp, kind=
dp)*rotation_generator, &
115 eigenvectors, eigenvalues)
116 norm = maxval(abs(eigenvalues))
117 DEALLOCATE (eigenvalues, eigenvectors)
129 weighted_energy_response, local_curvature_sum, fixed_n_curvature_sum)
RESULT(mu_shift)
130 REAL(kind=
dp),
INTENT(IN) :: weighted_energy_response, &
131 local_curvature_sum, &
132 fixed_n_curvature_sum
133 REAL(kind=
dp) :: mu_shift
135 REAL(kind=
dp) :: denominator
137 denominator = fixed_n_curvature_sum
138 IF (abs(denominator) <= epsilon(denominator)) denominator = local_curvature_sum
140 IF (abs(denominator) > epsilon(denominator)) mu_shift = weighted_energy_response/denominator
154 rayleigh_energy, energy_coordinate, response_weight, fixed_n_weight_sum, &
155 fixed_n_weighted_residual, gradient)
156 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: rayleigh_energy, energy_coordinate, &
158 REAL(kind=
dp),
INTENT(IN) :: fixed_n_weight_sum, &
159 fixed_n_weighted_residual
160 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: gradient
162 REAL(kind=
dp) :: fixed_n_mean
164 fixed_n_mean = 0.0_dp
165 IF (abs(fixed_n_weight_sum) > epsilon(fixed_n_weight_sum))
THEN
166 fixed_n_mean = fixed_n_weighted_residual/fixed_n_weight_sum
168 gradient(:) = response_weight(:)* &
169 (fixed_n_mean - (rayleigh_energy(:) - energy_coordinate(:)))
183 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: response_weight
184 REAL(kind=
dp),
INTENT(IN) :: fixed_n_weight_sum
185 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: hessian
189 n =
SIZE(response_weight)
190 hessian(:, :) = 0.0_dp
192 hessian(i, i) = response_weight(i)
194 IF (abs(fixed_n_weight_sum) > epsilon(fixed_n_weight_sum))
THEN
197 hessian(i, j) = hessian(i, j) - &
198 response_weight(i)*response_weight(j)/fixed_n_weight_sum
202 hessian(:, :) = 0.5_dp*(hessian + transpose(hessian))
227 rotation_hessian, rayleigh_response, response_weight, rotation_gradient, energy_gradient, &
228 schur_block, coupling_vector, schur_rhs)
229 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: rotation_hessian, rayleigh_response
230 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: response_weight, rotation_gradient, &
232 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: schur_block
233 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: coupling_vector, schur_rhs
236 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: response_group
237 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: coupling_matrix
239 nenergy =
SIZE(response_weight)
240 ALLOCATE (response_group(nenergy), coupling_matrix(
SIZE(coupling_vector), 1))
241 response_group(:) = 1
243 rotation_hessian, rayleigh_response, response_weight, response_group, &
244 rotation_gradient, energy_gradient, schur_block, coupling_matrix, schur_rhs)
245 coupling_vector(:) = coupling_matrix(:, 1)
246 DEALLOCATE (response_group, coupling_matrix)
268 rotation_hessian, rayleigh_response, response_weight, response_group, &
269 rotation_gradient, energy_gradient, schur_block, coupling_matrix, schur_rhs)
270 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: rotation_hessian, rayleigh_response
271 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: response_weight
272 INTEGER,
DIMENSION(:),
INTENT(IN) :: response_group
273 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: rotation_gradient, energy_gradient
274 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: schur_block, coupling_matrix
275 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: schur_rhs
277 INTEGER :: group, i, nenergy, ngroups, nrotation
278 REAL(kind=
dp) :: weight
280 nenergy =
SIZE(response_weight)
281 nrotation =
SIZE(rotation_gradient)
282 ngroups =
SIZE(coupling_matrix, 2)
283 cpassert(ngroups > 0)
284 cpassert(all(shape(rotation_hessian) == [nrotation, nrotation]))
285 cpassert(all(shape(rayleigh_response) == [nenergy, nrotation]))
286 cpassert(
SIZE(energy_gradient) == nenergy)
287 cpassert(
SIZE(response_group) == nenergy)
288 cpassert(all(response_group >= 1 .AND. response_group <= ngroups))
289 cpassert(all(shape(schur_block) == [nrotation, nrotation]))
290 cpassert(
SIZE(coupling_matrix, 1) == nrotation)
291 cpassert(
SIZE(schur_rhs) == nrotation)
293 schur_block(:, :) = rotation_hessian(:, :)
294 coupling_matrix(:, :) = 0.0_dp
296 weight = response_weight(i)
297 schur_block(:, :) = schur_block(:, :) - weight* &
298 spread(rayleigh_response(i, :), dim=2, ncopies=nrotation)* &
299 spread(rayleigh_response(i, :), dim=1, ncopies=nrotation)
300 group = response_group(i)
301 coupling_matrix(:, group) = coupling_matrix(:, group) + &
302 weight*rayleigh_response(i, :)
304 schur_block(:, :) = 0.5_dp*(schur_block + transpose(schur_block))
305 schur_rhs(:) = rotation_gradient + &
306 matmul(transpose(rayleigh_response), energy_gradient)
324 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: matrix, rhs
325 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: solution
326 LOGICAL,
INTENT(OUT) :: valid
327 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: relative_floor
329 INTEGER :: i, n, nresolved
330 REAL(kind=
dp) :: eigenvalue_floor, relative_floor_eff, &
332 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues
333 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: eigenvectors, work
336 cpassert(all(shape(matrix) == [n, n]))
337 cpassert(
SIZE(rhs, 1) == n)
338 cpassert(all(shape(solution) == shape(rhs)))
339 valid = all(matrix == matrix) .AND. all(rhs == rhs)
340 IF (.NOT. valid)
THEN
341 solution(:, :) = 0.0_dp
345 relative_floor_eff = sqrt(epsilon(1.0_dp))
346 IF (
PRESENT(relative_floor)) relative_floor_eff = max(relative_floor, relative_floor_eff)
347 ALLOCATE (eigenvalues(n), eigenvectors(n, n), work(n,
SIZE(rhs, 2)))
348 eigenvectors(:, :) = 0.5_dp*(matrix + transpose(matrix))
350 scale = max(1.0_dp, maxval(abs(eigenvalues)))
351 eigenvalue_floor = relative_floor_eff*scale
352 work(:, :) = matmul(transpose(eigenvectors), rhs)
355 IF (abs(eigenvalues(i)) > eigenvalue_floor)
THEN
356 work(i, :) = work(i, :)/abs(eigenvalues(i))
357 nresolved = nresolved + 1
362 solution(:, :) = matmul(eigenvectors, work)
363 valid = nresolved > 0 .AND. all(solution == solution)
364 IF (.NOT. valid) solution(:, :) = 0.0_dp
365 DEALLOCATE (eigenvalues, eigenvectors, work)
388 reference_hessian, response_correction, coefficients, valid, projected_gradient, relative_floor)
390 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: reference_hessian, response_correction
391 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: coefficients
392 LOGICAL,
INTENT(OUT) :: valid
393 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN),
OPTIONAL :: projected_gradient
394 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: relative_floor
397 REAL(kind=
dp) :: eigenvalue_floor, relative_floor_eff, &
399 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, rhs, work
400 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: eigenvectors
402 n =
SIZE(reference_hessian, 1)
404 cpassert(all(shape(reference_hessian) == [n, n]))
405 cpassert(all(shape(response_correction) == [n, n]))
406 cpassert(
SIZE(coefficients) == n)
407 IF (
PRESENT(projected_gradient))
THEN
408 cpassert(
SIZE(projected_gradient) == n)
410 coefficients(:) = 0.0_dp
411 valid = all(reference_hessian == reference_hessian) .AND. &
412 all(response_correction == response_correction)
413 IF (
PRESENT(projected_gradient))
THEN
414 valid = valid .AND. all(projected_gradient == projected_gradient)
416 IF (.NOT. valid)
RETURN
418 relative_floor_eff = 1.0e-4_dp
419 IF (
PRESENT(relative_floor)) relative_floor_eff = &
420 max(relative_floor, sqrt(epsilon(1.0_dp)))
421 ALLOCATE (eigenvalues(n), eigenvectors(n, n), rhs(n), work(n))
422 eigenvectors(:, :) = 0.5_dp* &
423 (reference_hessian + response_correction + &
424 transpose(reference_hessian + response_correction))
426 scale = max(maxval(abs(eigenvalues)), maxval(abs(reference_hessian)))
427 IF (scale <= tiny(scale))
THEN
429 coefficients(:) = 0.0_dp
430 DEALLOCATE (eigenvalues, eigenvectors, rhs, work)
433 eigenvalue_floor = relative_floor_eff*scale
434 valid = all(eigenvalues > eigenvalue_floor)
436 rhs(:) = reference_hessian(:, 1)
437 IF (
PRESENT(projected_gradient)) rhs(:) = projected_gradient
438 work(:) = matmul(transpose(eigenvectors), rhs)
440 work(i) = work(i)/eigenvalues(i)
442 coefficients(:) = matmul(eigenvectors, work)
443 valid = all(coefficients == coefficients) .AND. &
444 all(abs(coefficients) <= huge(1.0_dp))
446 IF (.NOT. valid) coefficients(:) = 0.0_dp
447 DEALLOCATE (eigenvalues, eigenvectors, rhs, work)
466 matrix, step, response, updated_matrix, valid, relative_tolerance)
467 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: matrix
468 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: step, response
469 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: updated_matrix
470 LOGICAL,
INTENT(OUT) :: valid
471 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: relative_tolerance
474 REAL(kind=
dp) :: denominator, residual_norm, step_norm, &
476 REAL(kind=
dp),
DIMENSION(SIZE(step)) :: residual
479 updated_matrix(:, :) = 0.0_dp
480 valid =
SIZE(response) == n .AND. all(shape(matrix) == [n, n]) .AND. &
481 all(shape(updated_matrix) == [n, n])
482 IF (.NOT. valid)
RETURN
483 valid = all(matrix == matrix) .AND. all(step == step) .AND. all(response == response)
484 IF (.NOT. valid)
RETURN
486 updated_matrix(:, :) = 0.5_dp*(matrix + transpose(matrix))
487 residual(:) = response - matmul(updated_matrix, step)
488 denominator = dot_product(residual, step)
489 residual_norm = sqrt(max(0.0_dp, dot_product(residual, residual)))
490 step_norm = sqrt(max(0.0_dp, dot_product(step, step)))
491 tolerance = sqrt(epsilon(1.0_dp))
492 IF (
PRESENT(relative_tolerance)) tolerance = max(tolerance, relative_tolerance)
493 threshold = tolerance*residual_norm*step_norm
494 valid = residual_norm > tiny(residual_norm) .AND. step_norm > tiny(step_norm) .AND. &
495 abs(denominator) > threshold
496 IF (.NOT. valid)
RETURN
498 updated_matrix(:, :) = updated_matrix + &
499 spread(residual, dim=2, ncopies=n)*spread(residual, dim=1, ncopies=n)/denominator
500 updated_matrix(:, :) = 0.5_dp*(updated_matrix + transpose(updated_matrix))
501 valid = all(updated_matrix == updated_matrix)
525 density_step, hamiltonian_step, density_modes, correction, valid, &
526 density_norm_sq, response_work)
528 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: density_step, hamiltonian_step
529 COMPLEX(KIND=dp),
DIMENSION(:, :, :),
INTENT(IN) :: density_modes
530 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: correction
531 LOGICAL,
INTENT(OUT) :: valid
532 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: density_norm_sq, response_work
534 INTEGER :: i, j, mode, n, nmode
535 REAL(kind=
dp) :: density_norm, density_response_work, &
537 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: density_overlap, response_overlap
539 n =
SIZE(density_step, 1)
540 nmode =
SIZE(density_modes, 3)
542 cpassert(
SIZE(density_step, 2) == n)
543 cpassert(all(shape(hamiltonian_step) == [n, n]))
544 cpassert(
SIZE(density_modes, 1) == n)
545 cpassert(
SIZE(density_modes, 2) == n)
546 cpassert(all(shape(correction) == [nmode, nmode]))
548 correction(:, :) = 0.0_dp
550 density_norm = 0.0_dp
551 density_response_work = 0.0_dp
554 density_norm = density_norm + &
555 REAL(conjg(density_step(i, j))*density_step(i, j), kind=
dp)
556 density_response_work = density_response_work + &
557 REAL(conjg(density_step(i, j))*hamiltonian_step(i, j), kind=
dp)
560 IF (
PRESENT(density_norm_sq)) density_norm_sq = density_norm
561 IF (
PRESENT(response_work)) response_work = density_response_work
562 scale = maxval(abs(density_step))
563 IF (scale <= tiny(1.0_dp))
RETURN
564 IF (density_norm <= 64.0_dp*epsilon(1.0_dp)*scale*scale .OR. nmode <= 0)
RETURN
566 ALLOCATE (density_overlap(nmode), response_overlap(nmode))
568 density_overlap(mode) = sum(real(conjg(density_step)*density_modes(:, :, mode), kind=
dp))
569 response_overlap(mode) = sum(real(conjg(hamiltonian_step)*density_modes(:, :, mode), kind=
dp))
572 density_norm, density_response_work, density_overlap, response_overlap, correction, valid)
573 DEALLOCATE (density_overlap, response_overlap)
590 density_norm_sq, response_work, density_overlap, response_overlap, correction, valid, &
591 secant_mode, secant_position)
593 REAL(kind=
dp),
INTENT(IN) :: density_norm_sq, response_work
594 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: density_overlap, response_overlap
595 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: correction
596 LOGICAL,
INTENT(OUT) :: valid
597 INTEGER,
INTENT(IN),
OPTIONAL :: secant_mode
598 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: secant_position
600 INTEGER :: i, j, nmode
601 REAL(kind=
dp) :: inverse_density_norm
602 REAL(kind=
dp),
DIMENSION(SIZE(density_overlap)) :: projected_density_overlap, &
603 projected_response_overlap
605 nmode =
SIZE(density_overlap)
606 cpassert(
SIZE(response_overlap) == nmode)
607 cpassert(all(shape(correction) == [nmode, nmode]))
609 correction(:, :) = 0.0_dp
611 IF (nmode <= 0 .OR. density_norm_sq <= tiny(1.0_dp))
RETURN
612 IF (density_norm_sq /= density_norm_sq .OR. response_work /= response_work)
RETURN
613 IF (abs(density_norm_sq) > huge(1.0_dp) .OR. abs(response_work) > huge(1.0_dp))
RETURN
614 IF (any(density_overlap /= density_overlap) .OR. any(response_overlap /= response_overlap))
RETURN
615 IF (any(abs(density_overlap) > huge(1.0_dp)) .OR. &
616 any(abs(response_overlap) > huge(1.0_dp)))
RETURN
617 IF (
PRESENT(secant_mode) .NEQV.
PRESENT(secant_position))
RETURN
619 projected_density_overlap(:) = density_overlap
620 projected_response_overlap(:) = response_overlap
621 IF (
PRESENT(secant_mode))
THEN
622 IF (secant_mode < 1 .OR. secant_mode > nmode)
RETURN
623 IF (secant_position /= secant_position .OR. &
624 abs(secant_position) > huge(1.0_dp) .OR. &
625 abs(secant_position) <= sqrt(epsilon(1.0_dp)))
RETURN
628 projected_density_overlap(secant_mode) = density_norm_sq/secant_position
629 projected_response_overlap(secant_mode) = response_work/secant_position
632 inverse_density_norm = 1.0_dp/density_norm_sq
635 correction(i, j) = inverse_density_norm* &
636 (projected_response_overlap(i)*projected_density_overlap(j) + &
637 projected_density_overlap(i)*projected_response_overlap(j) - &
638 response_work*inverse_density_norm* &
639 projected_density_overlap(i)*projected_density_overlap(j))
642 correction(:, :) = 0.5_dp*(correction + transpose(correction))
643 valid = all(correction == correction) .AND. all(abs(correction) <= huge(1.0_dp))
644 IF (.NOT. valid) correction(:, :) = 0.0_dp
666 rotation_generator, occupation, kpoint_weight, rotation_step, &
667 weighted_occupation_step, density_tangent, difference_step)
669 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: rotation_generator
670 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: occupation
671 REAL(kind=
dp),
INTENT(IN) :: kpoint_weight
672 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: rotation_step, weighted_occupation_step
673 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(OUT) :: density_tangent
674 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: difference_step
676 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: direction, generator_minus, &
677 generator_plus, mode_ref, rotation, rotation_minus, rotation_plus, weighted_rotation
678 INTEGER :: i, j, n, nrotation, r
679 REAL(kind=
dp) :: step, step_scale
681 n =
SIZE(rotation_generator, 1)
682 nrotation = n*(n - 1)
684 cpassert(all(shape(rotation_generator) == [n, n]))
685 cpassert(
SIZE(occupation) == n)
686 cpassert(
SIZE(rotation_step) == nrotation)
687 cpassert(
SIZE(weighted_occupation_step) == n)
688 cpassert(all(shape(density_tangent) == [n, n]))
689 cpassert(kpoint_weight > 0.0_dp)
691 ALLOCATE (direction(n, n), generator_minus(n, n), generator_plus(n, n), &
692 mode_ref(n, n), rotation(n, n), rotation_minus(n, n), &
693 rotation_plus(n, n), weighted_rotation(n, n))
694 direction(:, :) = cmplx(0.0_dp, 0.0_dp, kind=
dp)
699 direction(i, j) = cmplx(rotation_step(r), 0.0_dp, kind=
dp)
700 direction(j, i) = -direction(i, j)
702 direction(i, j) = direction(i, j) + &
703 cmplx(0.0_dp, rotation_step(r), kind=
dp)
704 direction(j, i) = direction(j, i) + &
705 cmplx(0.0_dp, rotation_step(r), kind=
dp)
708 cpassert(r == nrotation)
710 step_scale = max(1.0_dp, maxval(abs(direction)))
711 step = 1.0e-5_dp/step_scale
712 IF (
PRESENT(difference_step)) step = difference_step/step_scale
713 cpassert(step > epsilon(step))
714 generator_plus(:, :) = rotation_generator + step*direction
715 generator_minus(:, :) = rotation_generator - step*direction
716 CALL qs_ot_dense_rotation_state(rotation_generator, rotation)
717 CALL qs_ot_dense_rotation_state(generator_plus, rotation_plus)
718 CALL qs_ot_dense_rotation_state(generator_minus, rotation_minus)
720 weighted_rotation(:, :) = rotation_plus
722 weighted_rotation(:, j) = kpoint_weight*occupation(j)*weighted_rotation(:, j)
724 mode_ref(:, :) = matmul(weighted_rotation, conjg(transpose(rotation_plus)))
725 weighted_rotation(:, :) = rotation_minus
727 weighted_rotation(:, j) = kpoint_weight*occupation(j)*weighted_rotation(:, j)
729 mode_ref(:, :) = (mode_ref - &
730 matmul(weighted_rotation, conjg(transpose(rotation_minus))))/(2.0_dp*step)
732 weighted_rotation(:, :) = rotation
734 weighted_rotation(:, j) = weighted_occupation_step(j)*weighted_rotation(:, j)
736 mode_ref(:, :) = mode_ref + matmul(weighted_rotation, conjg(transpose(rotation)))
737 density_tangent(:, :) = matmul(conjg(transpose(rotation)), matmul(mode_ref, rotation))
738 density_tangent(:, :) = 0.5_dp*(density_tangent + conjg(transpose(density_tangent)))
740 DEALLOCATE (direction, generator_minus, generator_plus, mode_ref, rotation, &
741 rotation_minus, rotation_plus, weighted_rotation)
765 overlap_start_current, occupation_start, occupation_current, hamiltonian_step_start, &
766 hamiltonian_step_current, density_modes, kpoint_weight, density_norm_sq, response_work, &
767 density_overlap, response_overlap, valid)
769 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: overlap_start_current
770 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: occupation_start, occupation_current
771 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: hamiltonian_step_start, &
772 hamiltonian_step_current
773 COMPLEX(KIND=dp),
DIMENSION(:, :, :),
INTENT(IN) :: density_modes
774 REAL(kind=
dp),
INTENT(IN) :: kpoint_weight
775 REAL(kind=
dp),
INTENT(OUT) :: density_norm_sq, response_work
776 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: density_overlap, response_overlap
777 LOGICAL,
INTENT(OUT) :: valid
779 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: cross_mode
780 INTEGER :: i, j, mode, n, nmode
781 REAL(kind=
dp) :: cross_density, density_scale
783 n =
SIZE(occupation_start)
784 nmode =
SIZE(density_modes, 3)
786 cpassert(
SIZE(occupation_current) == n)
787 cpassert(all(shape(overlap_start_current) == [n, n]))
788 cpassert(all(shape(hamiltonian_step_start) == [n, n]))
789 cpassert(all(shape(hamiltonian_step_current) == [n, n]))
790 cpassert(
SIZE(density_modes, 1) == n .AND.
SIZE(density_modes, 2) == n)
791 cpassert(
SIZE(density_overlap) == nmode .AND.
SIZE(response_overlap) == nmode)
793 density_norm_sq = 0.0_dp
794 response_work = 0.0_dp
795 density_overlap(:) = 0.0_dp
796 response_overlap(:) = 0.0_dp
798 IF (nmode <= 0 .OR. kpoint_weight <= tiny(1.0_dp))
RETURN
800 cross_density = 0.0_dp
803 cross_density = cross_density + occupation_start(i)*occupation_current(j)* &
804 abs(overlap_start_current(i, j))**2
807 density_norm_sq = kpoint_weight* &
808 (sum(occupation_start**2) + sum(occupation_current**2) - &
809 2.0_dp*cross_density)
810 response_work = 0.0_dp
812 response_work = response_work + kpoint_weight* &
813 (occupation_current(i)*real(hamiltonian_step_current(i, i), kind=
dp) - &
814 occupation_start(i)*real(hamiltonian_step_start(i, i), kind=
dp))
817 ALLOCATE (cross_mode(n, n))
820 CALL gemm_square(overlap_start_current,
"N", density_modes(:, :, mode),
"N", &
821 overlap_start_current,
"C", cross_mode)
823 density_overlap(mode) = density_overlap(mode) + &
824 occupation_current(i)* &
825 REAL(density_modes(i, i, mode), kind=
dp) - &
826 occupation_start(i)*real(cross_mode(i, i), kind=
dp)
828 response_overlap(mode) = &
829 sum(real(hamiltonian_step_current, kind=
dp)* &
830 REAL(density_modes(:, :, mode), kind=
dp) + &
831 aimag(hamiltonian_step_current)*aimag(density_modes(:, :, mode)))
833 DEALLOCATE (cross_mode)
835 density_scale = kpoint_weight* &
836 max(maxval(abs(occupation_start)), maxval(abs(occupation_current)))
837 IF (density_scale <= tiny(1.0_dp))
RETURN
838 IF (density_norm_sq <= 64.0_dp*epsilon(1.0_dp)*density_scale**2)
RETURN
839 valid = density_norm_sq == density_norm_sq .AND. response_work == response_work .AND. &
840 abs(density_norm_sq) <= huge(1.0_dp) .AND. abs(response_work) <= huge(1.0_dp) .AND. &
841 all(density_overlap == density_overlap) .AND. &
842 all(response_overlap == response_overlap) .AND. &
843 all(abs(density_overlap) <= huge(1.0_dp)) .AND. &
844 all(abs(response_overlap) <= huge(1.0_dp))
845 IF (.NOT. valid)
THEN
846 density_norm_sq = 0.0_dp
847 response_work = 0.0_dp
848 density_overlap(:) = 0.0_dp
849 response_overlap(:) = 0.0_dp
870 chc, dchc, occupation, kpoint_weight, response_weight, fixed_n_weight_sum, &
871 projector_derivative, density_factor)
872 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: chc, dchc
873 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: occupation
874 REAL(kind=
dp),
INTENT(IN) :: kpoint_weight
875 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: response_weight
876 REAL(kind=
dp),
INTENT(IN) :: fixed_n_weight_sum
877 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(OUT) :: projector_derivative
878 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: density_factor
880 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: eigenvectors, kernel, work
882 REAL(kind=
dp) :: coefficient, denominator, factor, &
883 gap_tolerance, local_weight_sum, &
884 mu_numerator, mu_shift, scale
885 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, weighted_occupation
889 cpassert(all(shape(chc) == [n, n]))
890 cpassert(all(shape(dchc) == [n, n]))
891 cpassert(
SIZE(occupation) == n)
892 cpassert(
SIZE(response_weight) == n)
893 cpassert(all(shape(projector_derivative) == [n, n]))
896 IF (
PRESENT(density_factor)) factor = density_factor
897 projector_derivative(:, :) = cmplx(0.0_dp, 0.0_dp, kind=
dp)
898 IF (factor == 0.0_dp .OR. kpoint_weight <= 0.0_dp)
RETURN
900 ALLOCATE (eigenvectors(n, n), kernel(n, n), work(n, n), eigenvalues(n), &
901 weighted_occupation(n))
903 work(:, :) = matmul(conjg(transpose(eigenvectors)), matmul(dchc, eigenvectors))
904 weighted_occupation(:) = factor*kpoint_weight*occupation(:)
906 local_weight_sum = sum(response_weight(:))
907 mu_numerator = 0.0_dp
909 mu_numerator = mu_numerator + response_weight(i)* &
910 REAL(work(i, i), kind=
dp)
915 scale = max(1.0_dp, maxval(abs(eigenvalues(:))))
916 gap_tolerance = sqrt(epsilon(1.0_dp))*scale
917 kernel(:, :) = cmplx(0.0_dp, 0.0_dp, kind=
dp)
921 coefficient = -factor*response_weight(i)
922 kernel(i, i) = cmplx(coefficient*(real(work(i, i), kind=
dp) - mu_shift), &
925 denominator = eigenvalues(i) - eigenvalues(j)
926 IF (abs(denominator) > gap_tolerance)
THEN
927 coefficient = (weighted_occupation(i) - weighted_occupation(j))/denominator
929 coefficient = -0.5_dp*factor*(response_weight(i) + response_weight(j))
931 kernel(i, j) = coefficient*work(i, j)
936 projector_derivative(:, :) = matmul(eigenvectors, &
937 matmul(kernel, conjg(transpose(eigenvectors))))
938 projector_derivative(:, :) = 0.5_dp*(projector_derivative + &
939 conjg(transpose(projector_derivative)))
941 DEALLOCATE (eigenvectors, kernel, work, eigenvalues, weighted_occupation)
962 chc, rotation_generator, occupation, kpoint_weight, rotation_gradient, &
963 rotation_hessian, rayleigh_response, difference_step)
964 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: chc, rotation_generator
965 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: occupation
966 REAL(kind=
dp),
INTENT(IN) :: kpoint_weight
967 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: rotation_gradient
968 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: rotation_hessian, rayleigh_response
969 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: difference_step
971 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: base_hamiltonian, generator_minus, &
972 generator_plus, rotation
973 INTEGER :: i, j, n, nrotation, r, s
974 REAL(kind=
dp) :: step
975 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: occupation_scale, rayleigh, &
976 rayleigh_minus, rayleigh_plus
977 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: gradient_imag, gradient_minus_imag, &
978 gradient_minus_real, gradient_plus_imag, gradient_plus_real, gradient_real
981 nrotation = n*(n - 1)
983 cpassert(all(shape(chc) == [n, n]))
984 cpassert(all(shape(rotation_generator) == [n, n]))
985 cpassert(
SIZE(occupation) == n)
986 cpassert(
SIZE(rotation_gradient) == nrotation)
987 cpassert(all(shape(rotation_hessian) == [nrotation, nrotation]))
988 cpassert(all(shape(rayleigh_response) == [n, nrotation]))
989 cpassert(kpoint_weight > 0.0_dp)
992 IF (
PRESENT(difference_step)) step = difference_step
993 cpassert(step > sqrt(epsilon(step)))
995 ALLOCATE (base_hamiltonian(n, n), generator_minus(n, n), generator_plus(n, n), &
996 rotation(n, n), occupation_scale(n), rayleigh(n), rayleigh_minus(n), &
997 rayleigh_plus(n), gradient_imag(n, n), gradient_minus_imag(n, n), &
998 gradient_minus_real(n, n), gradient_plus_imag(n, n), &
999 gradient_plus_real(n, n), gradient_real(n, n))
1001 CALL qs_ot_dense_rotation_state(rotation_generator, rotation)
1002 base_hamiltonian(:, :) = matmul(rotation, matmul(chc, conjg(transpose(rotation))))
1003 occupation_scale(:) = 2.0_dp*kpoint_weight*occupation(:)
1004 CALL qs_ot_dense_rotation_gradient(rotation_generator, base_hamiltonian, occupation_scale, &
1005 gradient_real, gradient_imag, rayleigh)
1011 rotation_gradient(r) = gradient_real(i, j)
1013 rotation_gradient(r) = gradient_imag(i, j)
1016 cpassert(r == nrotation)
1021 generator_plus(:, :) = rotation_generator(:, :)
1022 generator_minus(:, :) = rotation_generator(:, :)
1023 generator_plus(i, j) = generator_plus(i, j) + step
1024 generator_plus(j, i) = generator_plus(j, i) - step
1025 generator_minus(i, j) = generator_minus(i, j) - step
1026 generator_minus(j, i) = generator_minus(j, i) + step
1028 CALL qs_ot_dense_rotation_gradient(generator_plus, base_hamiltonian, occupation_scale, &
1029 gradient_plus_real, gradient_plus_imag, rayleigh_plus)
1030 CALL qs_ot_dense_rotation_gradient(generator_minus, base_hamiltonian, occupation_scale, &
1031 gradient_minus_real, gradient_minus_imag, rayleigh_minus)
1032 CALL qs_ot_pack_rotation_response( &
1033 gradient_plus_real, gradient_plus_imag, gradient_minus_real, gradient_minus_imag, &
1034 rayleigh_plus, rayleigh_minus, step, rotation_hessian(:, s), &
1035 rayleigh_response(:, s))
1037 generator_plus(:, :) = rotation_generator(:, :)
1038 generator_minus(:, :) = rotation_generator(:, :)
1039 generator_plus(i, j) = generator_plus(i, j) + cmplx(0.0_dp, step, kind=
dp)
1040 generator_plus(j, i) = generator_plus(j, i) + cmplx(0.0_dp, step, kind=
dp)
1041 generator_minus(i, j) = generator_minus(i, j) - cmplx(0.0_dp, step, kind=
dp)
1042 generator_minus(j, i) = generator_minus(j, i) - cmplx(0.0_dp, step, kind=
dp)
1044 CALL qs_ot_dense_rotation_gradient(generator_plus, base_hamiltonian, occupation_scale, &
1045 gradient_plus_real, gradient_plus_imag, rayleigh_plus)
1046 CALL qs_ot_dense_rotation_gradient(generator_minus, base_hamiltonian, occupation_scale, &
1047 gradient_minus_real, gradient_minus_imag, rayleigh_minus)
1048 CALL qs_ot_pack_rotation_response( &
1049 gradient_plus_real, gradient_plus_imag, gradient_minus_real, gradient_minus_imag, &
1050 rayleigh_plus, rayleigh_minus, step, rotation_hessian(:, s), &
1051 rayleigh_response(:, s))
1054 cpassert(s == nrotation)
1055 rotation_hessian(:, :) = 0.5_dp*(rotation_hessian + transpose(rotation_hessian))
1057 DEALLOCATE (base_hamiltonian, generator_minus, generator_plus, rotation, occupation_scale, &
1058 rayleigh, rayleigh_minus, rayleigh_plus, gradient_imag, gradient_minus_imag, &
1059 gradient_minus_real, gradient_plus_imag, gradient_plus_real, gradient_real)
1075 SUBROUTINE qs_ot_pack_rotation_response( &
1076 gradient_plus_real, gradient_plus_imag, gradient_minus_real, gradient_minus_imag, &
1077 rayleigh_plus, rayleigh_minus, step, hessian_column, rayleigh_column)
1078 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: gradient_plus_real, gradient_plus_imag, &
1079 gradient_minus_real, &
1081 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: rayleigh_plus, rayleigh_minus
1082 REAL(kind=
dp),
INTENT(IN) :: step
1083 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: hessian_column, rayleigh_column
1085 INTEGER :: i, j, n, r
1087 n =
SIZE(gradient_plus_real, 1)
1088 cpassert(all(shape(gradient_plus_real) == [n, n]))
1089 cpassert(all(shape(gradient_plus_imag) == [n, n]))
1090 cpassert(all(shape(gradient_minus_real) == [n, n]))
1091 cpassert(all(shape(gradient_minus_imag) == [n, n]))
1092 cpassert(
SIZE(hessian_column) == n*(n - 1))
1093 cpassert(
SIZE(rayleigh_column) == n)
1099 hessian_column(r) = &
1100 (gradient_plus_real(i, j) - gradient_minus_real(i, j))/(2.0_dp*step)
1102 hessian_column(r) = &
1103 (gradient_plus_imag(i, j) - gradient_minus_imag(i, j))/(2.0_dp*step)
1106 rayleigh_column(:) = (rayleigh_plus(:) - rayleigh_minus(:))/(2.0_dp*step)
1108 END SUBROUTINE qs_ot_pack_rotation_response
1119 SUBROUTINE qs_ot_dense_rotation_gradient( &
1120 rotation_generator, base_hamiltonian, occupation_scale, gradient_real, gradient_imag, rayleigh)
1121 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: rotation_generator, base_hamiltonian
1122 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: occupation_scale
1123 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: gradient_real, gradient_imag
1124 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: rayleigh
1126 COMPLEX(KIND=dp) :: kernel
1127 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: covector, eigenvectors, frechet, inner, &
1128 outer, rotation, work
1130 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues
1132 n =
SIZE(rotation_generator, 1)
1133 ALLOCATE (covector(n, n), eigenvectors(n, n), frechet(n, n), inner(n, n), &
1134 outer(n, n), rotation(n, n), work(n, n), eigenvalues(n))
1135 CALL qs_ot_dense_rotation_state(rotation_generator, rotation, &
1136 eigenvectors=eigenvectors, eigenvalues=eigenvalues)
1138 work(:, :) = matmul(base_hamiltonian, rotation)
1139 covector(:, :) = work(:, :)
1141 covector(:, j) = occupation_scale(j)*covector(:, j)
1144 work(:, :) = matmul(conjg(transpose(rotation)), &
1145 matmul(base_hamiltonian, rotation))
1147 rayleigh(i) = real(work(i, i), kind=
dp)
1150 inner(:, :) = matmul(conjg(transpose(eigenvectors)), &
1151 matmul(covector, eigenvectors))
1155 outer(i, j) = inner(i, j)*kernel
1158 frechet(:, :) = matmul(eigenvectors, &
1159 matmul(outer, conjg(transpose(eigenvectors))))
1160 gradient_real(:, :) = real(frechet, kind=
dp) - transpose(real(frechet, kind=
dp))
1161 gradient_imag(:, :) = aimag(frechet) + transpose(aimag(frechet))
1163 DEALLOCATE (covector, eigenvectors, frechet, inner, outer, rotation, work, eigenvalues)
1165 END SUBROUTINE qs_ot_dense_rotation_gradient
1174 SUBROUTINE qs_ot_dense_rotation_state(rotation_generator, rotation, eigenvectors, eigenvalues)
1175 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: rotation_generator
1176 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(OUT) :: rotation
1177 COMPLEX(KIND=dp),
DIMENSION(:, :),
INTENT(OUT), &
1178 OPTIONAL :: eigenvectors
1179 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT),
OPTIONAL :: eigenvalues
1181 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: vectors, weighted_vectors
1183 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: values
1185 n =
SIZE(rotation_generator, 1)
1186 ALLOCATE (vectors(n, n), weighted_vectors(n, n), values(n))
1187 CALL diag_complex(cmplx(0.0_dp, 1.0_dp, kind=
dp)*rotation_generator, &
1189 weighted_vectors(:, :) = vectors(:, :)
1191 weighted_vectors(:, j) = exp(cmplx(0.0_dp, -values(j), kind=
dp))* &
1192 weighted_vectors(:, j)
1194 rotation(:, :) = matmul(weighted_vectors, conjg(transpose(vectors)))
1195 IF (
PRESENT(eigenvectors)) eigenvectors(:, :) = vectors(:, :)
1196 IF (
PRESENT(eigenvalues)) eigenvalues(:) = values(:)
1197 DEALLOCATE (vectors, weighted_vectors, values)
1199 END SUBROUTINE qs_ot_dense_rotation_state
1208 REAL(kind=
dp),
INTENT(IN) :: e1, e2
1209 COMPLEX(KIND=dp) :: kernel
1211 COMPLEX(KIND=dp) :: l1, l2, x
1214 l1 = (0.0_dp, -1.0_dp)*e1
1215 l2 = (0.0_dp, -1.0_dp)*e2
1216 IF (abs(l1 - l2) > 0.5_dp)
THEN
1217 kernel = (exp(l1) - exp(l2))/(l1 - l2)
1223 x = x*(l1 - l2)/real(i + 1, kind=
dp)
1225 kernel = kernel*exp(l2)
1240 outer_deriv_re, outer_deriv_im, adjoint)
1241 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: evals
1242 TYPE(
dbcsr_type) :: inner_deriv_re, inner_deriv_im, &
1243 outer_deriv_re, outer_deriv_im
1244 LOGICAL,
INTENT(IN),
OPTIONAL :: adjoint
1246 COMPLEX(KIND=dp) :: cval_in, kernel
1247 INTEGER :: col, i, j, max_blocks, nblocks, row
1248 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: cols, rows
1249 INTEGER,
DIMENSION(:),
POINTER :: col_blk_offset, col_blk_size, &
1250 row_blk_offset, row_blk_size
1251 LOGICAL :: found_im, found_out_im, found_out_re, &
1252 found_re, use_adjoint
1253 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_in_im, block_in_re, block_out_im, &
1255 REAL(kind=
dp) :: e1, e2, im_part, re_part
1259 use_adjoint = .false.
1260 IF (
PRESENT(adjoint)) use_adjoint = adjoint
1268 max_blocks = max_blocks + 1
1274 max_blocks = max_blocks + 1
1277 ALLOCATE (rows(max(max_blocks, 1)), cols(max(max_blocks, 1)))
1283 CALL append_union_block(row, col)
1289 CALL append_union_block(row, col)
1293 CALL dbcsr_get_info(inner_deriv_re, distribution=dist, row_blk_size=row_blk_size, &
1294 col_blk_size=col_blk_size)
1295 CALL dbcsr_create(outer_deriv_re,
"outer_deriv_re", dist, dbcsr_type_no_symmetry, &
1296 row_blk_size, col_blk_size)
1297 CALL dbcsr_create(outer_deriv_im,
"outer_deriv_im", dist, dbcsr_type_no_symmetry, &
1298 row_blk_size, col_blk_size)
1299 IF (nblocks > 0)
THEN
1308 CALL dbcsr_get_info(outer_deriv_re, row_blk_offset=row_blk_offset, &
1309 col_blk_offset=col_blk_offset)
1317 cpassert(found_out_re .AND. found_out_im)
1319 DO i = 1,
SIZE(block_out_re, 1)
1320 DO j = 1,
SIZE(block_out_re, 2)
1321 e1 = evals(row_blk_offset(row) + i - 1)
1322 e2 = evals(col_blk_offset(col) + j - 1)
1325 IF (found_re) re_part = block_in_re(i, j)
1326 IF (found_im) im_part = block_in_im(i, j)
1327 cval_in = cmplx(re_part, im_part,
dp)
1329 IF (use_adjoint) kernel = conjg(kernel)
1330 cval_in = cval_in*kernel
1331 block_out_re(i, j) = real(cval_in, kind=
dp)
1332 block_out_im(i, j) = aimag(cval_in)
1337 DEALLOCATE (rows, cols)
1346 SUBROUTINE append_union_block(row_new, col_new)
1347 INTEGER,
INTENT(IN) :: row_new, col_new
1351 DO iblock = 1, nblocks
1352 IF (rows(iblock) == row_new .AND. cols(iblock) == col_new)
RETURN
1354 nblocks = nblocks + 1
1355 rows(nblocks) = row_new
1356 cols(nblocks) = col_new
1357 END SUBROUTINE append_union_block
1377 qs_ot_env%os_valid = .false.
1378 IF (.NOT.
ASSOCIATED(qs_ot_env%matrix_psc0))
THEN
1380 CALL dbcsr_copy(qs_ot_env%matrix_psc0, qs_ot_env%matrix_sc0,
'matrix_psc0')
1382 IF (qs_ot_env%has_complex_kpoint_state .AND. &
1383 .NOT.
ASSOCIATED(qs_ot_env%matrix_psc0_im))
THEN
1385 CALL dbcsr_copy(qs_ot_env%matrix_psc0_im, qs_ot_env%matrix_sc0_im,
'matrix_psc0_im')
1388 IF (.NOT. qs_ot_env%use_dx)
THEN
1389 qs_ot_env%use_dx = .true.
1391 CALL dbcsr_copy(qs_ot_env%matrix_dx, qs_ot_env%matrix_gx,
'matrix_dx')
1392 IF (qs_ot_env%has_complex_kpoint_state)
THEN
1394 CALL dbcsr_copy(qs_ot_env%matrix_dx_im, qs_ot_env%matrix_gx_im,
'matrix_dx_im')
1396 IF (qs_ot_env%settings%do_rotation)
THEN
1398 CALL dbcsr_copy(qs_ot_env%rot_mat_dx, qs_ot_env%rot_mat_gx,
'rot_mat_dx')
1399 IF (qs_ot_env%has_complex_kpoint_state)
THEN
1401 CALL dbcsr_copy(qs_ot_env%rot_mat_dx_im, qs_ot_env%rot_mat_gx_im,
'rot_mat_dx_im')
1404 IF (qs_ot_env%settings%do_ener)
THEN
1405 ncoef =
SIZE(qs_ot_env%ener_gx)
1406 ALLOCATE (qs_ot_env%ener_dx(ncoef))
1407 qs_ot_env%ener_dx = 0.0_dp
1425 SUBROUTINE qs_ot_complex_multiply(op_a, op_b, a_re, a_im, b_re, b_im, c_re, c_im, tmp)
1426 CHARACTER(LEN=1),
INTENT(IN) :: op_a, op_b
1427 TYPE(
dbcsr_type) :: a_re, a_im, b_re, b_im, c_re, c_im, tmp
1429 CHARACTER(LEN=1) :: db_op_a, db_op_b
1430 REAL(kind=
dp) :: sign_a, sign_b
1440 cpabort(
"Complex matrix product expects N or C for op_a")
1450 cpabort(
"Complex matrix product expects N or C for op_b")
1453 CALL dbcsr_multiply(db_op_a, db_op_b, 1.0_dp, a_re, b_re, 0.0_dp, c_re)
1454 CALL dbcsr_multiply(db_op_a, db_op_b, 1.0_dp, a_im, b_im, 0.0_dp, tmp)
1455 CALL dbcsr_add(c_re, tmp, alpha_scalar=1.0_dp, beta_scalar=-sign_a*sign_b)
1457 CALL dbcsr_multiply(db_op_a, db_op_b, sign_b, a_re, b_im, 0.0_dp, c_im)
1458 CALL dbcsr_multiply(db_op_a, db_op_b, sign_a, a_im, b_re, 0.0_dp, tmp)
1459 CALL dbcsr_add(c_im, tmp, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
1461 END SUBROUTINE qs_ot_complex_multiply
1471 SUBROUTINE qs_ot_on_the_fly_localize(qs_ot_env, C_NEW, SC, G_OLD, D)
1474 TYPE(
dbcsr_type),
POINTER :: c_new, sc, g_old, d
1476 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_on_the_fly_localize'
1477 INTEGER,
PARAMETER :: taylor_order = 50
1478 REAL(kind=
dp),
PARAMETER :: alpha = 0.1_dp, f2_eps = 0.01_dp
1480 INTEGER :: col, col_size, handle, i, k, n, p, row, &
1482 REAL(
dp),
DIMENSION(:, :),
POINTER :: block
1483 REAL(kind=
dp) :: expfactor, f2, norm_fro, norm_gct, tmp
1486 TYPE(
dbcsr_type),
POINTER :: c, gp1, gp2, gu, u
1489 CALL timeset(routinen, handle)
1495 gu => qs_ot_env%buf1_k_k_nosym
1496 u => qs_ot_env%buf2_k_k_nosym
1497 gp1 => qs_ot_env%buf3_k_k_nosym
1498 gp2 => qs_ot_env%buf4_k_k_nosym
1499 c => qs_ot_env%buf1_n_k
1511 tmp = sqrt(block(i, p)**2 + f2_eps)
1513 block(i, p) = block(i, p)/tmp
1527 use_distribution=dist, &
1528 transpose_distribution=.false.)
1529 CALL dbcsr_add(gu, u, alpha_scalar=-0.5_dp, beta_scalar=0.5_dp)
1551 DO i = 2, taylor_order
1556 expfactor = expfactor/real(i, kind=
dp)
1557 CALL dbcsr_add(u, gp1, alpha_scalar=1.0_dp, beta_scalar=expfactor)
1560 IF (norm_fro*expfactor < 1.0e-10_dp)
EXIT
1576 IF (
ASSOCIATED(g_old))
THEN
1581 CALL timestop(handle)
1582 END SUBROUTINE qs_ot_on_the_fly_localize
1594 SUBROUTINE qs_ot_ref_chol(qs_ot_env, C_OLD, C_TMP, C_NEW, P, SC, update)
1597 TYPE(
dbcsr_type) :: c_old, c_tmp, c_new, p, sc
1598 LOGICAL,
INTENT(IN) :: update
1600 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_ref_chol'
1602 INTEGER :: handle, k, n
1604 CALL timeset(routinen, handle)
1613 transa=
"N", para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
1618 transa=
"N", para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
1622 CALL timestop(handle)
1623 END SUBROUTINE qs_ot_ref_chol
1635 SUBROUTINE qs_ot_ref_lwdn(qs_ot_env, C_OLD, C_TMP, C_NEW, P, SC, update)
1638 TYPE(
dbcsr_type) :: c_old, c_tmp, c_new, p, sc
1639 LOGICAL,
INTENT(IN) :: update
1641 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_ref_lwdn'
1643 INTEGER :: handle, i, k, n
1644 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: eig, fun
1647 CALL timeset(routinen, handle)
1651 v => qs_ot_env%buf1_k_k_nosym
1652 w => qs_ot_env%buf2_k_k_nosym
1653 ALLOCATE (eig(k), fun(k))
1655 CALL cp_dbcsr_syevd(p, v, eig, qs_ot_env%para_env, qs_ot_env%blacs_env)
1659 IF (eig(i) <= 0.0_dp)
THEN
1660 cpabort(
"P not positive definite")
1662 IF (eig(i) < 1.0e-8_dp)
THEN
1665 fun(i) = 1.0_dp/sqrt(eig(i))
1681 DEALLOCATE (eig, fun)
1683 CALL timestop(handle)
1684 END SUBROUTINE qs_ot_ref_lwdn
1697 SUBROUTINE qs_ot_ref_poly(qs_ot_env, C_OLD, C_TMP, C_NEW, P, SC, norm_in, update)
1700 TYPE(
dbcsr_type),
POINTER :: c_old, c_tmp, c_new, p
1702 REAL(
dp),
INTENT(IN) :: norm_in
1703 LOGICAL,
INTENT(IN) :: update
1705 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_ref_poly'
1707 INTEGER :: handle, irefine, k, n
1708 LOGICAL :: quick_exit
1709 REAL(
dp) :: norm, norm_fro, norm_gct, occ_in, &
1711 TYPE(
dbcsr_type),
POINTER :: buf1, buf2, buf_nosym, ft, fy
1713 CALL timeset(routinen, handle)
1717 buf_nosym => qs_ot_env%buf1_k_k_nosym
1718 buf1 => qs_ot_env%buf1_k_k_sym
1719 buf2 => qs_ot_env%buf2_k_k_sym
1720 fy => qs_ot_env%buf3_k_k_sym
1721 ft => qs_ot_env%buf4_k_k_sym
1727 quick_exit = .false.
1728 IF (norm < qs_ot_env%settings%eps_irac_quick_exit) quick_exit = .true.
1732 DO irefine = 1, qs_ot_env%settings%max_irac
1735 IF (norm > 1.0_dp)
THEN
1737 rescale = rescale/sqrt(norm)
1741 CALL qs_ot_refine(p, fy, buf1, buf2, qs_ot_env%settings%irac_degree, &
1742 qs_ot_env%settings%eps_irac_filter_matrix)
1745 IF (irefine == 1)
THEN
1749 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
1751 CALL dbcsr_filter(buf1, qs_ot_env%settings%eps_irac_filter_matrix)
1758 IF (quick_exit)
THEN
1764 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
1766 CALL dbcsr_filter(buf_nosym, qs_ot_env%settings%eps_irac_filter_matrix)
1770 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
1772 CALL dbcsr_filter(p, qs_ot_env%settings%eps_irac_filter_matrix)
1781 norm = min(norm_gct, norm_fro)
1786 IF (norm > 1.0e10_dp)
THEN
1787 CALL cp_abort(__location__, &
1788 "Refinement blows up! "// &
1789 "We need you to improve the code, please post your input on "// &
1790 "the forum https://www.cp2k.org/")
1794 IF (norm < qs_ot_env%settings%eps_irac_quick_exit) quick_exit = .true.
1797 IF (norm < qs_ot_env%settings%eps_irac)
EXIT
1803 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
1805 CALL dbcsr_filter(c_new, qs_ot_env%settings%eps_irac_filter_matrix)
1812 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
1814 CALL dbcsr_filter(c_tmp, qs_ot_env%settings%eps_irac_filter_matrix)
1820 CALL timestop(handle)
1821 END SUBROUTINE qs_ot_ref_poly
1828 FUNCTION qs_ot_ref_update(qs_ot_env1)
RESULT(update)
1834 SELECT CASE (qs_ot_env1%settings%ot_method)
1836 SELECT CASE (qs_ot_env1%settings%line_search_method)
1838 IF (qs_ot_env1%line_search_count == 2) update = .true.
1844 CASE (
"BROY",
"LBFG")
1850 END FUNCTION qs_ot_ref_update
1858 SUBROUTINE qs_ot_ref_decide(qs_ot_env1, norm_in, ortho_irac)
1861 REAL(
dp),
INTENT(IN) :: norm_in
1862 CHARACTER(LEN=*),
INTENT(INOUT) :: ortho_irac
1864 ortho_irac = qs_ot_env1%settings%ortho_irac
1865 IF (norm_in < qs_ot_env1%settings%eps_irac_switch) ortho_irac =
"POLY"
1866 END SUBROUTINE qs_ot_ref_decide
1880 matrix_gx_old, matrix_dx, qs_ot_env, qs_ot_env1)
1882 TYPE(
dbcsr_type),
POINTER :: matrix_c, matrix_s, matrix_x, matrix_sx, &
1883 matrix_gx_old, matrix_dx
1886 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_orbitals_ref'
1888 CHARACTER(LEN=4) :: ortho_irac
1889 INTEGER :: handle, k, n
1890 LOGICAL :: on_the_fly_loc, update
1891 REAL(
dp) :: norm, norm_fro, norm_gct, occ_in, occ_out
1892 TYPE(
dbcsr_type),
POINTER :: c_new, c_old, c_tmp, d, g_old, p, s, sc
1894 CALL timeset(routinen, handle)
1896 CALL dbcsr_get_info(matrix_c, nfullrows_total=n, nfullcols_total=k)
1901 g_old => matrix_gx_old
1905 p => qs_ot_env%p_k_k_sym
1906 c_tmp => qs_ot_env%buf1_n_k
1909 update = qs_ot_ref_update(qs_ot_env1)
1915 on_the_fly_loc = qs_ot_env1%settings%on_the_fly_loc
1918 IF (
ASSOCIATED(s))
THEN
1920 IF (qs_ot_env1%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
1922 CALL dbcsr_filter(sc, qs_ot_env1%settings%eps_irac_filter_matrix)
1931 IF (qs_ot_env1%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
1933 CALL dbcsr_filter(p, qs_ot_env1%settings%eps_irac_filter_matrix)
1942 norm = min(norm_gct, norm_fro)
1943 CALL qs_ot_ref_decide(qs_ot_env1, norm, ortho_irac)
1946 SELECT CASE (ortho_irac)
1948 CALL qs_ot_ref_chol(qs_ot_env, c_old, c_tmp, c_new, p, sc, update)
1950 CALL qs_ot_ref_lwdn(qs_ot_env, c_old, c_tmp, c_new, p, sc, update)
1952 CALL qs_ot_ref_poly(qs_ot_env, c_old, c_tmp, c_new, p, sc, norm, update)
1954 cpabort(
"Wrong argument")
1959 IF (on_the_fly_loc)
THEN
1960 CALL qs_ot_on_the_fly_localize(qs_ot_env, c_new, sc, g_old, d)
1965 IF (qs_ot_env%settings%do_rotation)
THEN
1967 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_new, qs_ot_env%rot_mat_u, &
1972 CALL timestop(handle)
1985 qs_ot_env, qs_ot_env1)
1987 TYPE(
dbcsr_type),
POINTER :: matrix_c, matrix_c_im, matrix_s, &
1992 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_orbitals_ref_complex'
1994 INTEGER :: handle, i, k, n
1996 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, inverse_sqrt
1997 TYPE(
dbcsr_type) :: rotated_im, rotated_re, rotation_tmp
1998 TYPE(
dbcsr_type),
POINTER :: c_im, c_re, f_im, f_re, p_im, p_re, &
1999 sc_im, sc_re, tmp_kk, tmp_nk, v_im, &
2002 CALL timeset(routinen, handle)
2004 cpassert(qs_ot_env%has_complex_kpoint_state)
2005 cpassert(
ASSOCIATED(matrix_s))
2006 cpassert(
ASSOCIATED(matrix_s_im))
2008 c_re => qs_ot_env%matrix_x
2009 c_im => qs_ot_env%matrix_x_im
2010 f_re => qs_ot_env%matrix_ref_inv_sqrt
2011 f_im => qs_ot_env%matrix_ref_inv_sqrt_im
2012 sc_re => qs_ot_env%matrix_sx
2013 sc_im => qs_ot_env%matrix_sx_im
2014 p_re => qs_ot_env%buf1_k_k_sym
2015 p_im => qs_ot_env%buf2_k_k_sym
2016 v_re => qs_ot_env%buf3_k_k_sym
2017 v_im => qs_ot_env%buf4_k_k_sym
2018 w_re => qs_ot_env%buf1_k_k_nosym
2019 w_im => qs_ot_env%buf2_k_k_nosym
2020 tmp_kk => qs_ot_env%buf3_k_k_nosym
2021 tmp_nk => qs_ot_env%buf1_n_k
2024 IF (
PRESENT(qs_ot_env1))
THEN
2025 update = qs_ot_ref_update(qs_ot_env1)
2027 update = qs_ot_ref_update(qs_ot_env)
2031 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, c_re, 0.0_dp, sc_re)
2032 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s_im, c_im, 0.0_dp, tmp_nk)
2033 CALL dbcsr_add(sc_re, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2035 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, c_im, 0.0_dp, sc_im)
2036 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s_im, c_re, 0.0_dp, tmp_nk)
2037 CALL dbcsr_add(sc_im, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2041 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, c_im, sc_im, 0.0_dp, tmp_kk)
2042 CALL dbcsr_add(p_re, tmp_kk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2045 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, c_im, sc_re, 0.0_dp, tmp_kk)
2046 CALL dbcsr_add(p_im, tmp_kk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2048 ALLOCATE (eigenvalues(k), inverse_sqrt(k))
2050 eigenvectors_re=v_re, eigenvectors_im=v_im, &
2051 eigenvalues=eigenvalues, para_env=qs_ot_env%para_env, &
2052 blacs_env=qs_ot_env%blacs_env)
2054 IF (eigenvalues(i) <= epsilon(1.0_dp))
THEN
2055 cpabort(
"Complex REF overlap is not positive definite")
2057 inverse_sqrt(i) = 1.0_dp/sqrt(eigenvalues(i))
2067 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, w_im, v_im, 0.0_dp, tmp_kk)
2068 CALL dbcsr_add(p_re, tmp_kk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2071 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, w_re, v_im, 0.0_dp, tmp_kk)
2072 CALL dbcsr_add(p_im, tmp_kk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2079 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_re, p_re, 0.0_dp, matrix_c)
2080 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_im, p_im, 0.0_dp, tmp_nk)
2081 CALL dbcsr_add(matrix_c, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2083 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_re, p_im, 0.0_dp, matrix_c_im)
2084 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_im, p_re, 0.0_dp, tmp_nk)
2085 CALL dbcsr_add(matrix_c_im, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2095 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, c_re, 0.0_dp, sc_re)
2096 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s_im, c_im, 0.0_dp, tmp_nk)
2097 CALL dbcsr_add(sc_re, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2099 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, c_im, 0.0_dp, sc_im)
2100 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s_im, c_re, 0.0_dp, tmp_nk)
2101 CALL dbcsr_add(sc_im, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2104 IF (qs_ot_env%settings%do_rotation)
THEN
2107 CALL dbcsr_copy(rotated_re, matrix_c, name=
"rotated_re")
2108 CALL dbcsr_copy(rotated_im, matrix_c_im, name=
"rotated_im")
2109 CALL dbcsr_copy(rotation_tmp, matrix_c, name=
"rotation_tmp")
2112 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_c, qs_ot_env%rot_mat_u, &
2114 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_c_im, qs_ot_env%rot_mat_u_im, &
2115 0.0_dp, rotation_tmp)
2116 CALL dbcsr_add(rotated_re, rotation_tmp, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2118 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_c, qs_ot_env%rot_mat_u_im, &
2120 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_c_im, qs_ot_env%rot_mat_u, &
2121 0.0_dp, rotation_tmp)
2122 CALL dbcsr_add(rotated_im, rotation_tmp, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2131 DEALLOCATE (eigenvalues, inverse_sqrt)
2133 CALL timestop(handle)
2145 SUBROUTINE qs_ot_refine(P, FY, P2, T, irac_degree, eps_irac_filter_matrix)
2146 TYPE(
dbcsr_type),
INTENT(inout) :: p, fy, p2, t
2147 INTEGER,
INTENT(in) :: irac_degree
2148 REAL(
dp),
INTENT(in) :: eps_irac_filter_matrix
2150 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_refine'
2152 INTEGER :: handle, k
2153 REAL(
dp) :: occ_in, occ_out, r
2155 CALL timeset(routinen, handle)
2158 SELECT CASE (irac_degree)
2163 IF (eps_irac_filter_matrix > 0.0_dp)
THEN
2169 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
2175 IF (eps_irac_filter_matrix > 0.0_dp)
THEN
2182 IF (eps_irac_filter_matrix > 0.0_dp)
THEN
2188 CALL dbcsr_add(fy, p2, alpha_scalar=1.0_dp, beta_scalar=r)
2189 r = -35.0_dp/16.0_dp
2190 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
2197 IF (eps_irac_filter_matrix > 0.0_dp)
THEN
2202 r = -180.0_dp/128.0_dp
2203 CALL dbcsr_add(t, p, alpha_scalar=0.0_dp, beta_scalar=r)
2204 r = 35.0_dp/128.0_dp
2205 CALL dbcsr_add(t, p2, alpha_scalar=1.0_dp, beta_scalar=r)
2207 IF (eps_irac_filter_matrix > 0.0_dp)
THEN
2212 r = 378.0_dp/128.0_dp
2213 CALL dbcsr_add(fy, p2, alpha_scalar=1.0_dp, beta_scalar=r)
2214 r = -420.0_dp/128.0_dp
2215 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
2216 r = 315.0_dp/128.0_dp
2219 cpabort(
"This irac_order NYI")
2221 CALL timestop(handle)
2222 END SUBROUTINE qs_ot_refine
2234 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
2237 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_ref'
2239 INTEGER :: handle, k, n
2240 REAL(
dp) :: occ_in, occ_out
2241 TYPE(
dbcsr_type),
POINTER :: c, chc, g, hc, hc_work, sc
2243 CALL timeset(routinen, handle)
2245 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
2251 chc => qs_ot_env%buf1_k_k_sym
2253 IF (qs_ot_env%settings%do_rotation)
THEN
2257 hc_work => qs_ot_env%buf1_n_k
2266 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
2268 CALL dbcsr_filter(chc, qs_ot_env%settings%eps_irac_filter_matrix)
2273 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
2275 CALL dbcsr_filter(g, qs_ot_env%settings%eps_irac_filter_matrix)
2279 CALL dbcsr_add(g, hc_work, alpha_scalar=-1.0_dp, beta_scalar=1.0_dp)
2281 CALL timestop(handle)
2293 matrix_hc_rotation, matrix_hc_rotation_im)
2294 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_hc_im
2296 TYPE(
dbcsr_type),
OPTIONAL,
POINTER :: matrix_hc_rotation, matrix_hc_rotation_im
2298 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_ref_complex'
2300 INTEGER :: handle, k, n
2301 REAL(
dp) :: occ_in, occ_out
2303 TYPE(
dbcsr_type),
POINTER :: b_im, b_re, f_im, f_re, g_im, g_re, hc_im, hc_re, &
2304 hc_rotation_im, hc_rotation_re, hc_work_im, hc_work_re, q_im, q_re, sc_im, sc_re, tmp_kk
2305 TYPE(
dbcsr_type),
TARGET :: hc_rot_im, hc_rot_re
2307 CALL timeset(routinen, handle)
2309 cpassert(qs_ot_env%has_complex_kpoint_state)
2310 cpassert(
ASSOCIATED(matrix_hc))
2311 cpassert(
ASSOCIATED(matrix_hc_im))
2313 f_re => qs_ot_env%matrix_ref_inv_sqrt
2314 f_im => qs_ot_env%matrix_ref_inv_sqrt_im
2315 sc_re => qs_ot_env%matrix_sx
2316 sc_im => qs_ot_env%matrix_sx_im
2318 hc_im => matrix_hc_im
2319 hc_rotation_re => hc_re
2320 hc_rotation_im => hc_im
2321 IF (
PRESENT(matrix_hc_rotation) .OR.
PRESENT(matrix_hc_rotation_im))
THEN
2322 cpassert(
PRESENT(matrix_hc_rotation) .AND.
PRESENT(matrix_hc_rotation_im))
2323 cpassert(
ASSOCIATED(matrix_hc_rotation))
2324 cpassert(
ASSOCIATED(matrix_hc_rotation_im))
2325 hc_rotation_re => matrix_hc_rotation
2326 hc_rotation_im => matrix_hc_rotation_im
2330 g_re => qs_ot_env%matrix_gx
2331 g_im => qs_ot_env%matrix_gx_im
2332 b_re => qs_ot_env%buf1_k_k_sym
2333 b_im => qs_ot_env%buf2_k_k_sym
2334 tmp_kk => qs_ot_env%buf3_k_k_sym
2335 q_re => qs_ot_env%buf1_n_k
2336 q_im => qs_ot_env%buf1_n_k_dp
2341 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env%matrix_x, f_re, 0.0_dp, q_re)
2342 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env%matrix_x_im, f_im, 0.0_dp, g_re)
2343 CALL dbcsr_add(q_re, g_re, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2345 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env%matrix_x, f_im, 0.0_dp, q_im)
2346 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env%matrix_x_im, f_re, 0.0_dp, g_re)
2347 CALL dbcsr_add(q_im, g_re, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2349 IF (qs_ot_env%settings%do_rotation)
THEN
2354 0.0_dp, qs_ot_env%rot_mat_dedu)
2355 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, q_im, hc_rotation_im, 0.0_dp, tmp_kk)
2356 CALL dbcsr_add(qs_ot_env%rot_mat_dedu, tmp_kk, &
2357 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2360 0.0_dp, qs_ot_env%rot_mat_dedu_im)
2361 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, q_im, hc_rotation_re, 0.0_dp, tmp_kk)
2362 CALL dbcsr_add(qs_ot_env%rot_mat_dedu_im, tmp_kk, &
2363 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2367 CALL dbcsr_copy(hc_rot_re, hc_re, name=
"hc_rot_re")
2368 CALL dbcsr_copy(hc_rot_im, hc_im, name=
"hc_rot_im")
2369 CALL dbcsr_copy(tmp_nk, hc_re, name=
"tmp_nk")
2370 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, hc_re, qs_ot_env%rot_mat_u, &
2372 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, hc_im, qs_ot_env%rot_mat_u_im, &
2374 CALL dbcsr_add(hc_rot_re, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2376 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, hc_im, qs_ot_env%rot_mat_u, &
2378 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, hc_re, qs_ot_env%rot_mat_u_im, &
2380 CALL dbcsr_add(hc_rot_im, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2381 hc_work_re => hc_rot_re
2382 hc_work_im => hc_rot_im
2386 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, q_re, hc_work_re, 0.0_dp, b_re)
2387 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, q_im, hc_work_im, 0.0_dp, tmp_kk)
2388 CALL dbcsr_add(b_re, tmp_kk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2390 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, q_re, hc_work_im, 0.0_dp, b_im)
2391 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, q_im, hc_work_re, 0.0_dp, tmp_kk)
2392 CALL dbcsr_add(b_im, tmp_kk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2394 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
2396 CALL dbcsr_filter(b_re, qs_ot_env%settings%eps_irac_filter_matrix)
2399 CALL dbcsr_filter(b_im, qs_ot_env%settings%eps_irac_filter_matrix)
2406 CALL dbcsr_add(g_re, q_re, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2410 CALL dbcsr_add(g_im, q_re, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2415 CALL dbcsr_add(q_re, q_im, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2419 CALL dbcsr_add(q_im, g_re, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2421 CALL dbcsr_add(q_re, hc_work_re, alpha_scalar=-1.0_dp, beta_scalar=1.0_dp)
2422 CALL dbcsr_add(q_im, hc_work_im, alpha_scalar=-1.0_dp, beta_scalar=1.0_dp)
2427 CALL dbcsr_add(g_re, g_im, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2431 CALL dbcsr_add(g_im, q_re, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2433 IF (qs_ot_env%settings%do_rotation)
THEN
2434 CALL qs_ot_add_ref_vertical_response_complex(b_re, b_im, f_re, f_im, &
2435 sc_re, sc_im, g_re, g_im, qs_ot_env)
2438 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
2440 CALL dbcsr_filter(g_re, qs_ot_env%settings%eps_irac_filter_matrix)
2443 CALL dbcsr_filter(g_im, qs_ot_env%settings%eps_irac_filter_matrix)
2447 IF (qs_ot_env%settings%do_rotation)
THEN
2453 CALL timestop(handle)
2463 SUBROUTINE qs_ot_square_transpose(matrix, transposed, identity_template)
2464 TYPE(
dbcsr_type) :: matrix, transposed, identity_template
2468 CALL dbcsr_copy(transposed, matrix, name=
'square_transposed')
2469 CALL dbcsr_copy(identity, identity_template, name=
'transpose_identity')
2472 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, matrix, identity, 0.0_dp, transposed)
2475 END SUBROUTINE qs_ot_square_transpose
2489 SUBROUTINE qs_ot_add_ref_vertical_response_complex(a_re, a_im, f_re, f_im, &
2490 sx_re, sx_im, gradient_re, gradient_im, &
2492 TYPE(
dbcsr_type) :: a_re, a_im, f_re, f_im, sx_re, sx_im, &
2493 gradient_re, gradient_im
2496 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_add_ref_vertical_response_complex'
2498 INTEGER :: col, handle, i, j, k, row
2499 INTEGER,
DIMENSION(:),
POINTER :: col_blk_offset, row_blk_offset
2500 LOGICAL :: found_im, found_re
2501 REAL(kind=
dp) :: denominator
2502 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: f_evals
2503 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: block_im, block_re
2505 TYPE(
dbcsr_type) :: anti_im, anti_re, f_work_im, f_work_re, inner_im, inner_re, sq_im, &
2506 sq_re, tmp_kk, tmp_nk, v_im, v_re, vertical_im, vertical_re, work_im, work_re, z_im, z_re
2508 CALL timeset(routinen, handle)
2512 CALL timestop(handle)
2518 CALL qs_ot_square_transpose(a_re, tmp_kk, qs_ot_env%rot_mat_u)
2519 CALL dbcsr_copy(anti_re, a_re, name=
'anti_re')
2520 CALL dbcsr_add(anti_re, tmp_kk, alpha_scalar=0.5_dp, beta_scalar=-0.5_dp)
2521 CALL qs_ot_square_transpose(a_im, tmp_kk, qs_ot_env%rot_mat_u)
2522 CALL dbcsr_copy(anti_im, a_im, name=
'anti_im')
2523 CALL dbcsr_add(anti_im, tmp_kk, alpha_scalar=0.5_dp, beta_scalar=0.5_dp)
2527 CALL dbcsr_copy(f_work_re, f_re, name=
'f_work_re')
2528 CALL dbcsr_copy(f_work_im, f_im, name=
'f_work_im')
2531 ALLOCATE (f_evals(k))
2533 eigenvectors_re=v_re, eigenvectors_im=v_im, eigenvalues=f_evals, &
2534 para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
2535 IF (minval(f_evals) <= epsilon(1.0_dp))
THEN
2536 cpabort(
'Complex REF inverse square root is not positive definite')
2540 CALL dbcsr_copy(work_re, anti_re, name=
'work_re')
2541 CALL dbcsr_copy(work_im, anti_im, name=
'work_im')
2542 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, anti_re, v_re, 0.0_dp, work_re)
2543 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, anti_im, v_im, 0.0_dp, tmp_kk)
2544 CALL dbcsr_add(work_re, tmp_kk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2545 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, anti_re, v_im, 0.0_dp, work_im)
2546 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, anti_im, v_re, 0.0_dp, tmp_kk)
2547 CALL dbcsr_add(work_im, tmp_kk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2549 CALL dbcsr_copy(inner_re, anti_re, name=
'inner_re')
2550 CALL dbcsr_copy(inner_im, anti_im, name=
'inner_im')
2551 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, v_re, work_re, 0.0_dp, inner_re)
2552 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, v_im, work_im, 1.0_dp, inner_re)
2553 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, v_re, work_im, 0.0_dp, inner_im)
2554 CALL dbcsr_multiply(
'T',
'N', -1.0_dp, v_im, work_re, 1.0_dp, inner_im)
2557 col_blk_offset=col_blk_offset)
2563 cpassert(found_re .AND. found_im)
2564 DO i = 1,
SIZE(block_re, 1)
2565 DO j = 1,
SIZE(block_re, 2)
2566 denominator = 1.0_dp/f_evals(row_blk_offset(row) + i - 1) + &
2567 1.0_dp/f_evals(col_blk_offset(col) + j - 1)
2568 block_re(i, j) = block_re(i, j)/denominator
2569 block_im(i, j) = block_im(i, j)/denominator
2576 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, v_re, inner_re, 0.0_dp, work_re)
2577 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, v_im, inner_im, 0.0_dp, tmp_kk)
2578 CALL dbcsr_add(work_re, tmp_kk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2579 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, v_re, inner_im, 0.0_dp, work_im)
2580 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, v_im, inner_re, 0.0_dp, tmp_kk)
2581 CALL dbcsr_add(work_im, tmp_kk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2585 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, work_re, v_re, 0.0_dp, z_re)
2586 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, work_im, v_im, 1.0_dp, z_re)
2587 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, work_im, v_re, 0.0_dp, z_im)
2588 CALL dbcsr_multiply(
'N',
'T', -1.0_dp, work_re, v_im, 1.0_dp, z_im)
2593 CALL dbcsr_copy(tmp_nk, sx_re, name=
'tmp_nk')
2594 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sx_re, f_re, 0.0_dp, sq_re)
2595 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sx_im, f_im, 0.0_dp, tmp_nk)
2596 CALL dbcsr_add(sq_re, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2597 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sx_re, f_im, 0.0_dp, sq_im)
2598 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sx_im, f_re, 0.0_dp, tmp_nk)
2599 CALL dbcsr_add(sq_im, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2601 CALL dbcsr_copy(vertical_re, sx_re, name=
'vertical_re')
2602 CALL dbcsr_copy(vertical_im, sx_im, name=
'vertical_im')
2603 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sq_re, z_re, 0.0_dp, vertical_re)
2604 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sq_im, z_im, 0.0_dp, tmp_nk)
2605 CALL dbcsr_add(vertical_re, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2606 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sq_re, z_im, 0.0_dp, vertical_im)
2607 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sq_im, z_re, 0.0_dp, tmp_nk)
2608 CALL dbcsr_add(vertical_im, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2609 CALL dbcsr_add(gradient_re, vertical_re, alpha_scalar=1.0_dp, beta_scalar=2.0_dp)
2610 CALL dbcsr_add(gradient_im, vertical_im, alpha_scalar=1.0_dp, beta_scalar=2.0_dp)
2612 DEALLOCATE (f_evals)
2632 CALL timestop(handle)
2634 END SUBROUTINE qs_ot_add_ref_vertical_response_complex
2644 TYPE(
dbcsr_type),
POINTER :: matrix_x, matrix_sx
2647 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_p'
2648 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
2650 INTEGER :: handle, k, max_iter, n
2651 LOGICAL :: converged
2652 REAL(kind=
dp) :: max_ev, min_ev, threshold
2654 CALL timeset(routinen, handle)
2656 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
2659 CALL dbcsr_multiply(
'T',
'N', rone, matrix_x, matrix_sx, rzero, &
2664 max_iter = 30; threshold = 1.0e-03_dp
2665 CALL arnoldi_extremal(qs_ot_env%matrix_p, max_ev, min_ev, converged, threshold, max_iter)
2666 qs_ot_env%largest_eval_upper_bound = max(max_ev, abs(min_ev))
2669 CALL decide_strategy(qs_ot_env)
2670 IF (qs_ot_env%do_taylor)
THEN
2671 CALL qs_ot_p2m_taylor(qs_ot_env)
2673 CALL qs_ot_p2m_diag(qs_ot_env)
2676 IF (qs_ot_env%settings%do_rotation)
THEN
2680 CALL timestop(handle)
2693 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_generate_rotation_complex'
2695 INTEGER :: handle, k
2696 REAL(kind=
dp) :: rot_norm
2697 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: exp_evals_im, exp_evals_re
2700 CALL timeset(routinen, handle)
2702 cpassert(qs_ot_env%has_complex_kpoint_state)
2703 cpassert(
ASSOCIATED(qs_ot_env%rot_mat_x_im))
2704 cpassert(
ASSOCIATED(qs_ot_env%rot_mat_u_im))
2710 IF (rot_norm <= epsilon(1.0_dp))
THEN
2711 CALL dbcsr_set(qs_ot_env%rot_mat_u, 0.0_dp)
2713 CALL dbcsr_set(qs_ot_env%rot_mat_u_im, 0.0_dp)
2714 CALL timestop(handle)
2720 CALL dbcsr_copy(h_re, qs_ot_env%rot_mat_x_im, name=
"h_re")
2722 CALL cp_dbcsr_heevd(matrix_re=h_re, matrix_im=qs_ot_env%rot_mat_x, &
2723 eigenvectors_re=qs_ot_env%rot_mat_evec_re, &
2724 eigenvectors_im=qs_ot_env%rot_mat_evec_im, &
2725 eigenvalues=qs_ot_env%rot_mat_evals, &
2726 para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
2728 ALLOCATE (exp_evals_re(k), exp_evals_im(k))
2729 exp_evals_re(:) = cos(-qs_ot_env%rot_mat_evals(:))
2730 exp_evals_im(:) = sin(-qs_ot_env%rot_mat_evals(:))
2732 CALL dbcsr_copy(w_re, qs_ot_env%rot_mat_evec_re, name=
"w_re")
2734 CALL dbcsr_copy(tmp, qs_ot_env%rot_mat_evec_im, name=
"tmp")
2736 CALL dbcsr_add(w_re, tmp, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2738 CALL dbcsr_copy(w_im, qs_ot_env%rot_mat_evec_im, name=
"w_im")
2740 CALL dbcsr_copy(tmp, qs_ot_env%rot_mat_evec_re)
2742 CALL dbcsr_add(w_im, tmp, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2744 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, w_re, qs_ot_env%rot_mat_evec_re, &
2745 0.0_dp, qs_ot_env%rot_mat_u)
2746 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, w_im, qs_ot_env%rot_mat_evec_im, &
2747 1.0_dp, qs_ot_env%rot_mat_u)
2748 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, w_im, qs_ot_env%rot_mat_evec_re, &
2749 0.0_dp, qs_ot_env%rot_mat_u_im)
2750 CALL dbcsr_multiply(
'N',
'T', -1.0_dp, w_re, qs_ot_env%rot_mat_evec_im, &
2751 1.0_dp, qs_ot_env%rot_mat_u_im)
2757 DEALLOCATE (exp_evals_re, exp_evals_im)
2760 CALL timestop(handle)
2772 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_rot_mat_derivative_complex'
2774 INTEGER :: handle, k
2775 REAL(kind=
dp) :: rot_norm
2776 TYPE(
dbcsr_type) :: frechet_im, frechet_re, inner_deriv_im, &
2777 inner_deriv_re, outer_deriv_im, &
2778 outer_deriv_re, tmp, work_im, work_re
2780 CALL timeset(routinen, handle)
2782 cpassert(qs_ot_env%has_complex_kpoint_state)
2783 cpassert(
ASSOCIATED(qs_ot_env%rot_mat_dedu_im))
2784 cpassert(
ASSOCIATED(qs_ot_env%rot_mat_gx_im))
2790 IF (rot_norm <= epsilon(1.0_dp))
THEN
2791 CALL qs_ot_square_transpose(qs_ot_env%rot_mat_dedu, tmp, qs_ot_env%rot_mat_u)
2792 CALL dbcsr_copy(qs_ot_env%rot_mat_gx, qs_ot_env%rot_mat_dedu)
2793 CALL dbcsr_add(qs_ot_env%rot_mat_gx, tmp, &
2794 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2797 CALL qs_ot_square_transpose(qs_ot_env%rot_mat_dedu_im, tmp, qs_ot_env%rot_mat_u)
2798 CALL dbcsr_copy(qs_ot_env%rot_mat_gx_im, qs_ot_env%rot_mat_dedu_im)
2799 CALL dbcsr_add(qs_ot_env%rot_mat_gx_im, tmp, &
2800 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2802 CALL timestop(handle)
2806 CALL dbcsr_copy(work_re, qs_ot_env%rot_mat_dedu, name=
"work_re")
2807 CALL dbcsr_copy(work_im, qs_ot_env%rot_mat_dedu, name=
"work_im")
2808 CALL dbcsr_copy(tmp, qs_ot_env%rot_mat_dedu, name=
"tmp")
2809 CALL dbcsr_copy(inner_deriv_re, qs_ot_env%rot_mat_dedu, name=
"inner_deriv_re")
2810 CALL dbcsr_copy(inner_deriv_im, qs_ot_env%rot_mat_dedu, name=
"inner_deriv_im")
2814 qs_ot_env%rot_mat_evec_re, 0.0_dp, work_re)
2815 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env%rot_mat_dedu_im, &
2816 qs_ot_env%rot_mat_evec_im, 0.0_dp, tmp)
2817 CALL dbcsr_add(work_re, tmp, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2819 qs_ot_env%rot_mat_evec_im, 0.0_dp, work_im)
2820 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env%rot_mat_dedu_im, &
2821 qs_ot_env%rot_mat_evec_re, 0.0_dp, tmp)
2822 CALL dbcsr_add(work_im, tmp, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2823 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, qs_ot_env%rot_mat_evec_re, &
2824 work_re, 0.0_dp, inner_deriv_re)
2825 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, qs_ot_env%rot_mat_evec_im, &
2826 work_im, 1.0_dp, inner_deriv_re)
2827 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, qs_ot_env%rot_mat_evec_re, &
2828 work_im, 0.0_dp, inner_deriv_im)
2829 CALL dbcsr_multiply(
'T',
'N', -1.0_dp, qs_ot_env%rot_mat_evec_im, &
2830 work_re, 1.0_dp, inner_deriv_im)
2833 inner_deriv_re, inner_deriv_im, &
2834 outer_deriv_re, outer_deriv_im, adjoint=.true.)
2836 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env%rot_mat_evec_re, &
2837 outer_deriv_re, 0.0_dp, work_re)
2838 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env%rot_mat_evec_im, &
2839 outer_deriv_im, 0.0_dp, tmp)
2840 CALL dbcsr_add(work_re, tmp, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2841 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env%rot_mat_evec_re, &
2842 outer_deriv_im, 0.0_dp, work_im)
2843 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, qs_ot_env%rot_mat_evec_im, &
2844 outer_deriv_re, 0.0_dp, tmp)
2845 CALL dbcsr_add(work_im, tmp, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2847 CALL dbcsr_copy(frechet_re, qs_ot_env%rot_mat_dedu, name=
"frechet_re")
2848 CALL dbcsr_copy(frechet_im, qs_ot_env%rot_mat_dedu, name=
"frechet_im")
2849 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, work_re, qs_ot_env%rot_mat_evec_re, &
2851 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, work_im, qs_ot_env%rot_mat_evec_im, &
2853 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, work_im, qs_ot_env%rot_mat_evec_re, &
2855 CALL dbcsr_multiply(
'N',
'T', -1.0_dp, work_re, qs_ot_env%rot_mat_evec_im, &
2859 CALL qs_ot_square_transpose(frechet_re, tmp, qs_ot_env%rot_mat_u)
2860 CALL dbcsr_copy(qs_ot_env%rot_mat_gx, frechet_re)
2861 CALL dbcsr_add(qs_ot_env%rot_mat_gx, tmp, &
2862 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2863 CALL qs_ot_square_transpose(frechet_im, tmp, qs_ot_env%rot_mat_u)
2864 CALL dbcsr_copy(qs_ot_env%rot_mat_gx_im, frechet_im)
2865 CALL dbcsr_add(qs_ot_env%rot_mat_gx_im, tmp, &
2866 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2879 CALL timestop(handle)
2892 TYPE(
dbcsr_type),
POINTER :: matrix_x, matrix_x_im, matrix_sx, &
2896 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_p_complex'
2900 CALL timeset(routinen, handle)
2902 cpassert(qs_ot_env%has_complex_kpoint_state)
2903 cpassert(qs_ot_env%settings%ot_algorithm ==
'TOD')
2905 CALL qs_ot_complex_multiply(
'C',
'N', matrix_x, matrix_x_im, matrix_sx, matrix_sx_im, &
2906 qs_ot_env%matrix_p, qs_ot_env%matrix_p_im, qs_ot_env%matrix_buf1)
2907 qs_ot_env%do_taylor = .false.
2908 CALL qs_ot_p2m_diag_complex(qs_ot_env)
2910 CALL timestop(handle)
2926 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_generate_rotation'
2928 INTEGER :: handle, k
2929 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: exp_evals_im, exp_evals_re
2932 CALL timeset(routinen, handle)
2942 eigenvectors_re=qs_ot_env%rot_mat_evec_re, &
2943 eigenvectors_im=qs_ot_env%rot_mat_evec_im, &
2944 eigenvalues=qs_ot_env%rot_mat_evals, &
2945 para_env=qs_ot_env%para_env, &
2946 blacs_env=qs_ot_env%blacs_env)
2949 ALLOCATE (exp_evals_re(k), exp_evals_im(k))
2950 exp_evals_re(:) = cos(-qs_ot_env%rot_mat_evals(:))
2951 exp_evals_im(:) = sin(-qs_ot_env%rot_mat_evals(:))
2955 CALL dbcsr_copy(buf_1, qs_ot_env%rot_mat_evec_re, name=
"buf_1")
2957 CALL dbcsr_copy(buf_2, qs_ot_env%rot_mat_evec_im, name=
"buf_2")
2959 CALL dbcsr_add(buf_1, buf_2, alpha_scalar=+1.0_dp, beta_scalar=-1.0_dp)
2960 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, buf_1, qs_ot_env%rot_mat_evec_re, 0.0_dp, qs_ot_env%rot_mat_u)
2962 CALL dbcsr_copy(buf_1, qs_ot_env%rot_mat_evec_im)
2964 CALL dbcsr_copy(buf_2, qs_ot_env%rot_mat_evec_re)
2966 CALL dbcsr_add(buf_1, buf_2, alpha_scalar=+1.0_dp, beta_scalar=+1.0_dp)
2967 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, buf_1, qs_ot_env%rot_mat_evec_im, 1.0_dp, qs_ot_env%rot_mat_u)
2972 DEALLOCATE (exp_evals_re, exp_evals_im)
2975 CALL timestop(handle)
2990 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_rot_mat_derivative'
2992 INTEGER :: col, handle, i, iblock, j, k, max_blocks, nblocks, row
2993 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: cols, rows
2994 INTEGER,
DIMENSION(:),
POINTER :: col_blk_offset, col_blk_size, row_blk_offset, row_blk_size
2995 REAL(kind=
dp) :: e1, e2
2996 TYPE(
dbcsr_type) :: outer_deriv_re, outer_deriv_im, mat_buf, &
2997 inner_deriv_re, inner_deriv_im
3000 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_in_re, block_in_im, block_out_re, block_out_im
3001 LOGICAL :: duplicate, found_in_im, found_in_re, found_out_im, &
3003 REAL(kind=
dp) :: im_part, re_part
3004 COMPLEX(dp) :: cval_in, cval_out
3005 CALL timeset(routinen, handle)
3009 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%rot_mat_dedu)
3011 CALL dbcsr_copy(mat_buf, qs_ot_env%rot_mat_dedu,
"mat_buf")
3014 CALL dbcsr_copy(inner_deriv_re, qs_ot_env%rot_mat_dedu,
"inner_deriv_re")
3015 CALL dbcsr_copy(inner_deriv_im, qs_ot_env%rot_mat_dedu,
"inner_deriv_im")
3017 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_dedu, qs_ot_env%rot_mat_evec_im, 0.0_dp, mat_buf)
3018 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_im, mat_buf, 0.0_dp, inner_deriv_re)
3019 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, mat_buf, 0.0_dp, inner_deriv_im)
3021 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_dedu, qs_ot_env%rot_mat_evec_re, 0.0_dp, mat_buf)
3022 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, mat_buf, 1.0_dp, inner_deriv_re)
3023 CALL dbcsr_multiply(
'T',
'N', -1.0_dp, qs_ot_env%rot_mat_evec_im, mat_buf, 1.0_dp, inner_deriv_im)
3031 max_blocks = max_blocks + 1
3037 max_blocks = max_blocks + 1
3041 ALLOCATE (rows(max(max_blocks, 1)), cols(max(max_blocks, 1)))
3047 DO iblock = 1, nblocks
3048 duplicate = duplicate .OR. (rows(iblock) == row .AND. cols(iblock) == col)
3050 IF (.NOT. duplicate)
THEN
3051 nblocks = nblocks + 1
3061 DO iblock = 1, nblocks
3062 duplicate = duplicate .OR. (rows(iblock) == row .AND. cols(iblock) == col)
3064 IF (.NOT. duplicate)
THEN
3065 nblocks = nblocks + 1
3072 CALL dbcsr_get_info(inner_deriv_re, distribution=dist, row_blk_size=row_blk_size, &
3073 col_blk_size=col_blk_size)
3074 CALL dbcsr_create(outer_deriv_re,
"outer_deriv_re", dist, dbcsr_type_no_symmetry, &
3075 row_blk_size, col_blk_size)
3076 CALL dbcsr_create(outer_deriv_im,
"outer_deriv_im", dist, dbcsr_type_no_symmetry, &
3077 row_blk_size, col_blk_size)
3078 IF (nblocks > 0)
THEN
3087 CALL dbcsr_get_info(outer_deriv_re, row_blk_offset=row_blk_offset, col_blk_offset=col_blk_offset)
3095 cpassert(found_out_re .AND. found_out_im)
3097 DO i = 1,
SIZE(block_out_re, 1)
3098 DO j = 1,
SIZE(block_out_re, 2)
3099 e1 = qs_ot_env%rot_mat_evals(row_blk_offset(row) + i - 1)
3100 e2 = qs_ot_env%rot_mat_evals(col_blk_offset(col) + j - 1)
3103 IF (found_in_re) re_part = block_in_re(i, j)
3104 IF (found_in_im) im_part = block_in_im(i, j)
3105 cval_in = cmplx(re_part, im_part,
dp)
3106 cval_out = cval_in*cint(e1, e2)
3107 block_out_re(i, j) = real(cval_out)
3108 block_out_im(i, j) = aimag(cval_out)
3113 DEALLOCATE (rows, cols)
3118 CALL dbcsr_multiply(
'N',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, outer_deriv_re, 0.0_dp, mat_buf)
3119 CALL dbcsr_multiply(
'N',
'N', -1.0_dp, qs_ot_env%rot_mat_evec_im, outer_deriv_im, 1.0_dp, mat_buf)
3120 CALL dbcsr_multiply(
'N',
'T', +1.0_dp, mat_buf, qs_ot_env%rot_mat_evec_re, 0.0_dp, qs_ot_env%matrix_buf1)
3122 CALL dbcsr_multiply(
'N',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, outer_deriv_im, 0.0_dp, mat_buf)
3123 CALL dbcsr_multiply(
'N',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_im, outer_deriv_re, 1.0_dp, mat_buf)
3124 CALL dbcsr_multiply(
'N',
'T', +1.0_dp, mat_buf, qs_ot_env%rot_mat_evec_im, 1.0_dp, qs_ot_env%matrix_buf1)
3128 CALL qs_ot_square_transpose(qs_ot_env%matrix_buf1, mat_buf, qs_ot_env%rot_mat_u)
3129 CALL dbcsr_copy(qs_ot_env%rot_mat_gx, mat_buf)
3130 CALL dbcsr_add(qs_ot_env%rot_mat_gx, qs_ot_env%matrix_buf1, &
3131 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
3137 CALL timestop(handle)
3146 FUNCTION cint(e1, e2)
3147 REAL(kind=
dp) :: e1, e2
3148 COMPLEX(KIND=dp) :: cint
3150 COMPLEX(KIND=dp) :: l1, l2, x
3153 l1 = (0.0_dp, -1.0_dp)*e1
3154 l2 = (0.0_dp, -1.0_dp)*e2
3155 IF (abs(l1 - l2) > 0.5_dp)
THEN
3156 cint = (exp(l1) - exp(l2))/(l1 - l2)
3162 x = x*(l1 - l2)/real(i + 1, kind=
dp)
3178 SUBROUTINE decide_strategy(qs_ot_env)
3182 REAL(kind=
dp) :: num_error
3184 qs_ot_env%do_taylor = .false.
3186 num_error = qs_ot_env%largest_eval_upper_bound/(2.0_dp)
3187 DO WHILE (num_error > qs_ot_env%settings%eps_taylor .AND. n <= qs_ot_env%settings%max_taylor)
3189 num_error = num_error*qs_ot_env%largest_eval_upper_bound/real((2*n + 1)*(2*n + 2), kind=
dp)
3191 qs_ot_env%taylor_order = n
3192 IF (qs_ot_env%taylor_order <= qs_ot_env%settings%max_taylor)
THEN
3193 qs_ot_env%do_taylor = .true.
3196 END SUBROUTINE decide_strategy
3208 TYPE(
dbcsr_type),
POINTER :: matrix_c, matrix_x
3211 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_orbitals'
3212 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
3214 INTEGER :: handle, k, n
3217 CALL timeset(routinen, handle)
3219 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
3223 IF (qs_ot_env%settings%do_rotation)
THEN
3224 matrix_kk => qs_ot_env%matrix_buf1
3226 qs_ot_env%rot_mat_u, rzero, matrix_kk)
3228 matrix_kk => qs_ot_env%matrix_cosp
3231 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_c0, matrix_kk, &
3234 IF (qs_ot_env%settings%do_rotation)
THEN
3235 matrix_kk => qs_ot_env%matrix_buf1
3237 qs_ot_env%rot_mat_u, rzero, matrix_kk)
3239 matrix_kk => qs_ot_env%matrix_sinp
3244 CALL timestop(handle)
3257 TYPE(
dbcsr_type),
POINTER :: matrix_c, matrix_c_im, matrix_s, &
3261 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_orbitals_complex'
3264 TYPE(
dbcsr_type) :: rotated_im, rotated_re, rotation_tmp
3266 CALL timeset(routinen, handle)
3268 cpassert(qs_ot_env%has_complex_kpoint_state)
3269 cpassert(qs_ot_env%settings%ot_algorithm ==
'TOD')
3271 CALL qs_ot_complex_multiply(
'N',
'N', matrix_s, matrix_s_im, &
3272 qs_ot_env%matrix_x, qs_ot_env%matrix_x_im, &
3273 qs_ot_env%matrix_sx, qs_ot_env%matrix_sx_im, &
3274 qs_ot_env%matrix_tmp_nk)
3276 qs_ot_env%matrix_sx, qs_ot_env%matrix_sx_im, qs_ot_env)
3278 CALL qs_ot_complex_multiply(
'N',
'N', qs_ot_env%matrix_c0, qs_ot_env%matrix_c0_im, &
3279 qs_ot_env%matrix_cosp, qs_ot_env%matrix_cosp_im, &
3280 matrix_c, matrix_c_im, qs_ot_env%matrix_tmp_nk)
3281 CALL qs_ot_complex_multiply(
'N',
'N', qs_ot_env%matrix_x, qs_ot_env%matrix_x_im, &
3282 qs_ot_env%matrix_sinp, qs_ot_env%matrix_sinp_im, &
3283 qs_ot_env%matrix_buf_nk, qs_ot_env%matrix_buf_nk_im, &
3284 qs_ot_env%matrix_tmp_nk)
3285 CALL dbcsr_add(matrix_c, qs_ot_env%matrix_buf_nk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3286 CALL dbcsr_add(matrix_c_im, qs_ot_env%matrix_buf_nk_im, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3288 IF (qs_ot_env%settings%do_rotation)
THEN
3291 CALL dbcsr_copy(rotated_re, matrix_c, name=
"strict_rotated_re")
3292 CALL dbcsr_copy(rotated_im, matrix_c_im, name=
"strict_rotated_im")
3293 CALL dbcsr_copy(rotation_tmp, matrix_c, name=
"strict_rotation_tmp")
3296 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_c, qs_ot_env%rot_mat_u, &
3298 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_c_im, qs_ot_env%rot_mat_u_im, &
3299 0.0_dp, rotation_tmp)
3300 CALL dbcsr_add(rotated_re, rotation_tmp, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
3302 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_c, qs_ot_env%rot_mat_u_im, &
3304 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_c_im, qs_ot_env%rot_mat_u, &
3305 0.0_dp, rotation_tmp)
3306 CALL dbcsr_add(rotated_im, rotation_tmp, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3315 CALL timestop(handle)
3332 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
3335 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative'
3336 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
3338 INTEGER :: handle, k, n, ortho_k
3339 TYPE(
dbcsr_type),
POINTER :: matrix_hc_local, matrix_target
3341 CALL timeset(routinen, handle)
3343 NULLIFY (matrix_hc_local)
3345 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
3350 IF (qs_ot_env%settings%do_rotation)
THEN
3353 CALL dbcsr_copy(matrix_hc_local, matrix_hc, name=
'matrix_hc_local')
3355 CALL dbcsr_multiply(
'N',
'T', rone, matrix_gx, qs_ot_env%rot_mat_u, rzero, matrix_hc_local)
3357 matrix_hc_local => matrix_hc
3360 IF (qs_ot_env%do_taylor)
THEN
3361 CALL qs_ot_get_derivative_taylor(matrix_hc_local, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
3363 CALL qs_ot_get_derivative_diag(matrix_hc_local, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
3367 CALL dbcsr_get_info(qs_ot_env%matrix_sc0, nfullcols_total=ortho_k)
3369 IF (
ASSOCIATED(qs_ot_env%preconditioner))
THEN
3370 matrix_target => qs_ot_env%matrix_psc0
3372 matrix_target => qs_ot_env%matrix_sc0
3375 IF (.NOT. qs_ot_env%os_valid)
THEN
3379 IF (
ASSOCIATED(qs_ot_env%preconditioner))
THEN
3381 qs_ot_env%matrix_psc0)
3384 qs_ot_env%matrix_sc0, matrix_target, &
3385 rzero, qs_ot_env%matrix_os)
3387 para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
3389 para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env, &
3390 uplo_to_full=.true.)
3391 qs_ot_env%os_valid = .true.
3394 rzero, qs_ot_env%matrix_buf1_ortho)
3396 qs_ot_env%matrix_buf1_ortho, rzero, qs_ot_env%matrix_buf2_ortho)
3398 qs_ot_env%matrix_buf2_ortho, rone, matrix_gx)
3400 IF (qs_ot_env%settings%do_rotation)
THEN
3404 IF (qs_ot_env%settings%do_rotation)
THEN
3408 CALL timestop(handle)
3420 LOGICAL,
INTENT(OUT),
OPTIONAL :: preconditioner_rejected
3423 REAL(kind=
dp) :: eval_scale, eval_threshold
3424 TYPE(
dbcsr_type),
POINTER :: target_im, target_re
3426 IF (
PRESENT(preconditioner_rejected)) preconditioner_rejected = .false.
3427 IF (qs_ot_env%os_valid)
RETURN
3429 IF (
ASSOCIATED(qs_ot_env%preconditioner))
THEN
3430 target_re => qs_ot_env%matrix_psc0
3431 target_im => qs_ot_env%matrix_psc0_im
3433 qs_ot_env%matrix_sc0, qs_ot_env%matrix_sc0_im, &
3434 target_re, target_im)
3436 target_re => qs_ot_env%matrix_sc0
3437 target_im => qs_ot_env%matrix_sc0_im
3439 CALL qs_ot_complex_multiply(
'C',
'N', qs_ot_env%matrix_sc0, qs_ot_env%matrix_sc0_im, &
3440 target_re, target_im, qs_ot_env%matrix_os, qs_ot_env%matrix_os_im, &
3441 qs_ot_env%matrix_buf1)
3443 CALL cp_dbcsr_heevd(matrix_re=qs_ot_env%matrix_os, matrix_im=qs_ot_env%matrix_os_im, &
3444 eigenvectors_re=qs_ot_env%matrix_r, eigenvectors_im=qs_ot_env%matrix_r_im, &
3445 eigenvalues=qs_ot_env%evals, para_env=qs_ot_env%para_env, &
3446 blacs_env=qs_ot_env%blacs_env)
3447 eval_scale = max(1.0_dp, maxval(abs(qs_ot_env%evals(1:k))))
3448 eval_threshold = 100.0_dp*epsilon(1.0_dp)*eval_scale
3449 IF (minval(qs_ot_env%evals(1:k)) <= eval_threshold .AND. &
3450 ASSOCIATED(qs_ot_env%preconditioner))
THEN
3451 NULLIFY (qs_ot_env%preconditioner)
3452 IF (
PRESENT(preconditioner_rejected)) preconditioner_rejected = .true.
3453 target_re => qs_ot_env%matrix_sc0
3454 target_im => qs_ot_env%matrix_sc0_im
3455 CALL qs_ot_complex_multiply(
'C',
'N', qs_ot_env%matrix_sc0, qs_ot_env%matrix_sc0_im, &
3456 target_re, target_im, qs_ot_env%matrix_os, qs_ot_env%matrix_os_im, &
3457 qs_ot_env%matrix_buf1)
3458 CALL cp_dbcsr_heevd(matrix_re=qs_ot_env%matrix_os, matrix_im=qs_ot_env%matrix_os_im, &
3459 eigenvectors_re=qs_ot_env%matrix_r, eigenvectors_im=qs_ot_env%matrix_r_im, &
3460 eigenvalues=qs_ot_env%evals, para_env=qs_ot_env%para_env, &
3461 blacs_env=qs_ot_env%blacs_env)
3462 eval_scale = max(1.0_dp, maxval(abs(qs_ot_env%evals(1:k))))
3463 eval_threshold = 100.0_dp*epsilon(1.0_dp)*eval_scale
3465 cpassert(minval(qs_ot_env%evals(1:k)) > eval_threshold)
3467 qs_ot_env%dum(i) = 1.0_dp/qs_ot_env%evals(i)
3469 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
3470 CALL dbcsr_copy(qs_ot_env%matrix_buf1_im, qs_ot_env%matrix_r_im)
3473 CALL qs_ot_complex_multiply(
'N',
'C', qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf1_im, &
3474 qs_ot_env%matrix_r, qs_ot_env%matrix_r_im, &
3475 qs_ot_env%matrix_os, qs_ot_env%matrix_os_im, &
3476 qs_ot_env%matrix_buf2)
3477 qs_ot_env%os_valid = .true.
3490 matrix_hc_rotation, matrix_hc_rotation_im)
3491 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_hc_im
3493 TYPE(
dbcsr_type),
OPTIONAL,
POINTER :: matrix_hc_rotation, matrix_hc_rotation_im
3495 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_complex'
3500 TYPE(
dbcsr_type),
POINTER :: hc_rotation_im, hc_rotation_re, &
3501 hc_work_im, hc_work_re, target_im, &
3503 TYPE(
dbcsr_type),
TARGET :: hc_rot_im, hc_rot_re
3505 CALL timeset(routinen, handle)
3507 cpassert(qs_ot_env%has_complex_kpoint_state)
3508 cpassert(qs_ot_env%settings%ot_algorithm ==
'TOD')
3510 hc_rotation_re => matrix_hc
3511 hc_rotation_im => matrix_hc_im
3512 IF (
PRESENT(matrix_hc_rotation) .OR.
PRESENT(matrix_hc_rotation_im))
THEN
3513 cpassert(
PRESENT(matrix_hc_rotation) .AND.
PRESENT(matrix_hc_rotation_im))
3514 cpassert(
ASSOCIATED(matrix_hc_rotation))
3515 cpassert(
ASSOCIATED(matrix_hc_rotation_im))
3516 hc_rotation_re => matrix_hc_rotation
3517 hc_rotation_im => matrix_hc_rotation_im
3519 hc_work_re => matrix_hc
3520 hc_work_im => matrix_hc_im
3522 IF (qs_ot_env%settings%do_rotation)
THEN
3526 CALL qs_ot_complex_multiply(
'N',
'N', qs_ot_env%matrix_c0, qs_ot_env%matrix_c0_im, &
3527 qs_ot_env%matrix_cosp, qs_ot_env%matrix_cosp_im, &
3528 qs_ot_env%matrix_buf_nk, qs_ot_env%matrix_buf_nk_im, &
3529 qs_ot_env%matrix_tmp_nk)
3530 CALL qs_ot_complex_multiply(
'N',
'N', qs_ot_env%matrix_x, qs_ot_env%matrix_x_im, &
3531 qs_ot_env%matrix_sinp, qs_ot_env%matrix_sinp_im, &
3532 qs_ot_env%matrix_gx, qs_ot_env%matrix_gx_im, &
3533 qs_ot_env%matrix_tmp_nk)
3534 CALL dbcsr_add(qs_ot_env%matrix_buf_nk, qs_ot_env%matrix_gx, &
3535 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3536 CALL dbcsr_add(qs_ot_env%matrix_buf_nk_im, qs_ot_env%matrix_gx_im, &
3537 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3540 CALL qs_ot_complex_multiply(
'C',
'N', &
3541 qs_ot_env%matrix_buf_nk, qs_ot_env%matrix_buf_nk_im, &
3542 hc_rotation_re, hc_rotation_im, &
3543 qs_ot_env%rot_mat_dedu, qs_ot_env%rot_mat_dedu_im, &
3544 qs_ot_env%matrix_buf1)
3548 CALL dbcsr_copy(hc_rot_re, matrix_hc, name=
"strict_hc_rot_re")
3549 CALL dbcsr_copy(hc_rot_im, matrix_hc_im, name=
"strict_hc_rot_im")
3550 CALL dbcsr_copy(tmp_nk, matrix_hc, name=
"strict_hc_rot_tmp")
3551 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, matrix_hc, qs_ot_env%rot_mat_u, &
3553 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, matrix_hc_im, qs_ot_env%rot_mat_u_im, &
3555 CALL dbcsr_add(hc_rot_re, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3557 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, matrix_hc_im, qs_ot_env%rot_mat_u, &
3559 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, matrix_hc, qs_ot_env%rot_mat_u_im, &
3561 CALL dbcsr_add(hc_rot_im, tmp_nk, alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
3562 hc_work_re => hc_rot_re
3563 hc_work_im => hc_rot_im
3567 CALL qs_ot_complex_multiply(
'N',
'N', hc_work_re, hc_work_im, &
3568 qs_ot_env%matrix_sinp, qs_ot_env%matrix_sinp_im, &
3569 qs_ot_env%matrix_gx, qs_ot_env%matrix_gx_im, &
3570 qs_ot_env%matrix_tmp_nk)
3573 CALL qs_ot_complex_multiply(
'C',
'N', hc_work_re, hc_work_im, &
3574 qs_ot_env%matrix_x, qs_ot_env%matrix_x_im, &
3575 qs_ot_env%matrix_buf2, qs_ot_env%matrix_buf2_im, &
3576 qs_ot_env%matrix_buf1)
3577 CALL qs_ot_complex_multiply(
'N',
'N', qs_ot_env%matrix_buf2, qs_ot_env%matrix_buf2_im, &
3578 qs_ot_env%matrix_r, qs_ot_env%matrix_r_im, &
3579 qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf1_im, &
3580 qs_ot_env%matrix_buf4)
3581 CALL qs_ot_complex_multiply(
'C',
'N', qs_ot_env%matrix_r, qs_ot_env%matrix_r_im, &
3582 qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf1_im, &
3583 qs_ot_env%matrix_buf2, qs_ot_env%matrix_buf2_im, &
3584 qs_ot_env%matrix_buf4)
3586 qs_ot_env%matrix_buf3)
3588 qs_ot_env%matrix_buf3_im)
3591 CALL qs_ot_complex_multiply(
'C',
'N', hc_work_re, hc_work_im, &
3592 qs_ot_env%matrix_c0, qs_ot_env%matrix_c0_im, &
3593 qs_ot_env%matrix_buf2, qs_ot_env%matrix_buf2_im, &
3594 qs_ot_env%matrix_buf1)
3595 CALL qs_ot_complex_multiply(
'N',
'N', qs_ot_env%matrix_buf2, qs_ot_env%matrix_buf2_im, &
3596 qs_ot_env%matrix_r, qs_ot_env%matrix_r_im, &
3597 qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf1_im, &
3598 qs_ot_env%matrix_buf4)
3599 CALL qs_ot_complex_multiply(
'C',
'N', qs_ot_env%matrix_r, qs_ot_env%matrix_r_im, &
3600 qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf1_im, &
3601 qs_ot_env%matrix_buf2, qs_ot_env%matrix_buf2_im, &
3602 qs_ot_env%matrix_buf4)
3604 qs_ot_env%matrix_buf4)
3606 qs_ot_env%matrix_buf4_im)
3607 CALL dbcsr_add(qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf4, &
3608 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3609 CALL dbcsr_add(qs_ot_env%matrix_buf3_im, qs_ot_env%matrix_buf4_im, &
3610 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3613 CALL qs_ot_complex_multiply(
'N',
'N', qs_ot_env%matrix_r, qs_ot_env%matrix_r_im, &
3614 qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf3_im, &
3615 qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf1_im, &
3616 qs_ot_env%matrix_buf2)
3617 CALL qs_ot_complex_multiply(
'N',
'C', qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf1_im, &
3618 qs_ot_env%matrix_r, qs_ot_env%matrix_r_im, &
3619 qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf3_im, &
3620 qs_ot_env%matrix_buf2)
3623 shallow_data_copy=.false., use_distribution=dist, &
3624 transpose_distribution=.false.)
3625 CALL dbcsr_transposed(qs_ot_env%matrix_buf4_im, qs_ot_env%matrix_buf3_im, &
3626 shallow_data_copy=.false., use_distribution=dist, &
3627 transpose_distribution=.false.)
3628 CALL dbcsr_add(qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf4, &
3629 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3630 CALL dbcsr_add(qs_ot_env%matrix_buf3_im, qs_ot_env%matrix_buf4_im, &
3631 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
3633 CALL qs_ot_complex_multiply(
'N',
'N', qs_ot_env%matrix_sx, qs_ot_env%matrix_sx_im, &
3634 qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf3_im, &
3635 qs_ot_env%matrix_buf_nk, qs_ot_env%matrix_buf_nk_im, &
3636 qs_ot_env%matrix_tmp_nk)
3637 CALL dbcsr_add(qs_ot_env%matrix_gx, qs_ot_env%matrix_buf_nk, &
3638 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3639 CALL dbcsr_add(qs_ot_env%matrix_gx_im, qs_ot_env%matrix_buf_nk_im, &
3640 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3644 IF (
ASSOCIATED(qs_ot_env%preconditioner))
THEN
3645 target_re => qs_ot_env%matrix_psc0
3646 target_im => qs_ot_env%matrix_psc0_im
3648 target_re => qs_ot_env%matrix_sc0
3649 target_im => qs_ot_env%matrix_sc0_im
3652 CALL qs_ot_complex_multiply(
'C',
'N', target_re, target_im, &
3653 qs_ot_env%matrix_gx, qs_ot_env%matrix_gx_im, &
3654 qs_ot_env%matrix_buf1_ortho, qs_ot_env%matrix_buf1_ortho_im, &
3655 qs_ot_env%matrix_tmp_ortho)
3656 CALL qs_ot_complex_multiply(
'N',
'N', qs_ot_env%matrix_os, qs_ot_env%matrix_os_im, &
3657 qs_ot_env%matrix_buf1_ortho, qs_ot_env%matrix_buf1_ortho_im, &
3658 qs_ot_env%matrix_buf2_ortho, qs_ot_env%matrix_buf2_ortho_im, &
3659 qs_ot_env%matrix_tmp_ortho)
3660 CALL qs_ot_complex_multiply(
'N',
'N', qs_ot_env%matrix_sc0, qs_ot_env%matrix_sc0_im, &
3661 qs_ot_env%matrix_buf2_ortho, qs_ot_env%matrix_buf2_ortho_im, &
3662 qs_ot_env%matrix_buf_nk, qs_ot_env%matrix_buf_nk_im, &
3663 qs_ot_env%matrix_tmp_nk)
3664 CALL dbcsr_add(qs_ot_env%matrix_gx, qs_ot_env%matrix_buf_nk, &
3665 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
3666 CALL dbcsr_add(qs_ot_env%matrix_gx_im, qs_ot_env%matrix_buf_nk_im, &
3667 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
3669 IF (qs_ot_env%settings%do_rotation)
THEN
3675 CALL timestop(handle)
3687 SUBROUTINE qs_ot_get_derivative_diag(matrix_hc, matrix_x, matrix_sx, matrix_gx, &
3690 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
3693 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_diag'
3694 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
3696 INTEGER :: handle, k, n
3699 CALL timeset(routinen, handle)
3701 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
3705 CALL dbcsr_multiply(
'N',
'N', rone, matrix_hc, qs_ot_env%matrix_sinp, rzero, matrix_gx)
3707 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, matrix_x, rzero, qs_ot_env%matrix_buf2)
3709 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_buf2, qs_ot_env%matrix_r, &
3710 rzero, qs_ot_env%matrix_buf1)
3711 CALL dbcsr_multiply(
'T',
'N', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
3712 rzero, qs_ot_env%matrix_buf2)
3716 qs_ot_env%matrix_buf3)
3719 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, qs_ot_env%matrix_c0, rzero, &
3720 qs_ot_env%matrix_buf2)
3722 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_buf2, qs_ot_env%matrix_r, &
3723 rzero, qs_ot_env%matrix_buf1)
3724 CALL dbcsr_multiply(
'T',
'N', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
3725 rzero, qs_ot_env%matrix_buf2)
3728 qs_ot_env%matrix_buf4)
3731 CALL dbcsr_add(qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf4, &
3732 alpha_scalar=rone, beta_scalar=rone)
3735 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_buf3, qs_ot_env%matrix_r, &
3736 rzero, qs_ot_env%matrix_buf1)
3737 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
3738 rzero, qs_ot_env%matrix_buf3)
3741 shallow_data_copy=.false., use_distribution=dist, &
3742 transpose_distribution=.false.)
3743 CALL dbcsr_add(qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf1, &
3744 alpha_scalar=rone, beta_scalar=rone)
3747 CALL dbcsr_multiply(
'N',
'N', rone, matrix_sx, qs_ot_env%matrix_buf3, &
3749 CALL timestop(handle)
3751 END SUBROUTINE qs_ot_get_derivative_diag
3761 SUBROUTINE qs_ot_get_derivative_taylor(matrix_hc, matrix_x, matrix_sx, matrix_gx, &
3764 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
3767 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_taylor'
3768 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
3770 INTEGER :: handle, i, k, n
3771 REAL(kind=
dp) :: cosfactor, sinfactor
3773 TYPE(
dbcsr_type),
POINTER :: matrix_left, matrix_right
3775 CALL timeset(routinen, handle)
3777 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
3781 CALL dbcsr_multiply(
'N',
'N', rone, matrix_hc, qs_ot_env%matrix_sinp, rzero, matrix_gx)
3783 IF (qs_ot_env%taylor_order <= 0)
THEN
3784 CALL timestop(handle)
3789 CALL dbcsr_set(qs_ot_env%matrix_r, rzero)
3792 matrix_left => qs_ot_env%matrix_cosp_b
3793 matrix_right => qs_ot_env%matrix_sinp_b
3796 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, matrix_x, rzero, matrix_left)
3799 shallow_data_copy=.false., use_distribution=dist, &
3800 transpose_distribution=.false.)
3801 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, &
3802 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
3806 sinfactor = -1.0_dp/(2.0_dp*3.0_dp)
3807 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
3808 alpha_scalar=1.0_dp, beta_scalar=sinfactor)
3814 DO i = 2, qs_ot_env%taylor_order
3815 sinfactor = sinfactor*(-1.0_dp)/real(2*i*(2*i + 1), kind=
dp)
3816 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_p, matrix_left, rzero, qs_ot_env%matrix_buf1)
3817 CALL dbcsr_multiply(
'N',
'N', rone, matrix_right, qs_ot_env%matrix_p, rzero, matrix_left)
3819 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, &
3821 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
3822 alpha_scalar=1.0_dp, beta_scalar=sinfactor)
3826 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, qs_ot_env%matrix_c0, rzero, matrix_left)
3829 shallow_data_copy=.false., use_distribution=dist, &
3830 transpose_distribution=.false.)
3831 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, 1.0_dp, 1.0_dp)
3835 cosfactor = -1.0_dp/(1.0_dp*2.0_dp)
3836 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
3837 alpha_scalar=1.0_dp, beta_scalar=cosfactor)
3843 DO i = 2, qs_ot_env%taylor_order
3844 cosfactor = cosfactor*(-1.0_dp)/real(2*i*(2*i - 1), kind=
dp)
3845 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_p, matrix_left, rzero, qs_ot_env%matrix_buf1)
3846 CALL dbcsr_multiply(
'N',
'N', rone, matrix_right, qs_ot_env%matrix_p, rzero, matrix_left)
3848 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, 1.0_dp, 1.0_dp)
3849 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
3850 alpha_scalar=1.0_dp, beta_scalar=cosfactor)
3854 CALL dbcsr_multiply(
'N',
'N', rone, matrix_sx, qs_ot_env%matrix_r, rone, matrix_gx)
3856 CALL timestop(handle)
3858 END SUBROUTINE qs_ot_get_derivative_taylor
3864 SUBROUTINE qs_ot_p2m_taylor(qs_ot_env)
3867 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_p2m_taylor'
3868 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
3870 INTEGER :: handle, i, k
3871 REAL(kind=
dp) :: cosfactor, sinfactor
3873 CALL timeset(routinen, handle)
3876 CALL dbcsr_set(qs_ot_env%matrix_cosp, rzero)
3877 CALL dbcsr_set(qs_ot_env%matrix_sinp, rzero)
3881 IF (qs_ot_env%taylor_order <= 0)
THEN
3882 CALL timestop(handle)
3887 cosfactor = -1.0_dp/(1.0_dp*2.0_dp)
3888 sinfactor = -1.0_dp/(2.0_dp*3.0_dp)
3889 CALL dbcsr_add(qs_ot_env%matrix_cosp, qs_ot_env%matrix_p, alpha_scalar=1.0_dp, beta_scalar=cosfactor)
3890 CALL dbcsr_add(qs_ot_env%matrix_sinp, qs_ot_env%matrix_p, alpha_scalar=1.0_dp, beta_scalar=sinfactor)
3891 IF (qs_ot_env%taylor_order <= 1)
THEN
3892 CALL timestop(handle)
3898 CALL dbcsr_copy(qs_ot_env%matrix_r, qs_ot_env%matrix_p)
3900 DO i = 2, qs_ot_env%taylor_order
3902 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_p, qs_ot_env%matrix_r, &
3903 rzero, qs_ot_env%matrix_buf1)
3904 CALL dbcsr_copy(qs_ot_env%matrix_r, qs_ot_env%matrix_buf1)
3906 cosfactor = cosfactor*(-1.0_dp)/real(2*i*(2*i - 1), kind=
dp)
3907 sinfactor = sinfactor*(-1.0_dp)/real(2*i*(2*i + 1), kind=
dp)
3908 CALL dbcsr_add(qs_ot_env%matrix_cosp, qs_ot_env%matrix_r, &
3909 alpha_scalar=1.0_dp, beta_scalar=cosfactor)
3910 CALL dbcsr_add(qs_ot_env%matrix_sinp, qs_ot_env%matrix_r, &
3911 alpha_scalar=1.0_dp, beta_scalar=sinfactor)
3914 CALL timestop(handle)
3916 END SUBROUTINE qs_ot_p2m_taylor
3926 SUBROUTINE qs_ot_p2m_diag(qs_ot_env)
3930 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_p2m_diag'
3931 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
3933 INTEGER :: col, col_offset, col_size, handle, i, j, &
3934 k, row, row_offset, row_size
3935 REAL(
dp),
DIMENSION(:, :),
POINTER :: block
3936 REAL(kind=
dp) :: a, b
3939 CALL timeset(routinen, handle)
3942 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_p)
3943 CALL cp_dbcsr_syevd(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r, qs_ot_env%evals, &
3944 qs_ot_env%para_env, qs_ot_env%blacs_env)
3946 qs_ot_env%evals(i) = max(0.0_dp, qs_ot_env%evals(i))
3951 qs_ot_env%dum(i) = cos(sqrt(qs_ot_env%evals(i)))
3953 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
3955 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
3956 rzero, qs_ot_env%matrix_cosp)
3960 qs_ot_env%dum(i) = qs_ot_sinc(sqrt(qs_ot_env%evals(i)))
3962 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
3964 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
3965 rzero, qs_ot_env%matrix_sinp)
3967 CALL dbcsr_copy(qs_ot_env%matrix_cosp_b, qs_ot_env%matrix_cosp)
3971 row_size=row_size, col_size=col_size, &
3972 row_offset=row_offset, col_offset=col_offset)
3975 a = (sqrt(qs_ot_env%evals(row_offset + i - 1)) &
3976 - sqrt(qs_ot_env%evals(col_offset + j - 1)))/2.0_dp
3977 b = (sqrt(qs_ot_env%evals(row_offset + i - 1)) &
3978 + sqrt(qs_ot_env%evals(col_offset + j - 1)))/2.0_dp
3979 block(i, j) = -0.5_dp*qs_ot_sinc(a)*qs_ot_sinc(b)
3985 CALL dbcsr_copy(qs_ot_env%matrix_sinp_b, qs_ot_env%matrix_sinp)
3989 row_size=row_size, col_size=col_size, &
3990 row_offset=row_offset, col_offset=col_offset)
3993 a = sqrt(qs_ot_env%evals(row_offset + i - 1))
3994 b = sqrt(qs_ot_env%evals(col_offset + j - 1))
3995 block(i, j) = qs_ot_sincf(a, b)
4001 CALL timestop(handle)
4003 END SUBROUTINE qs_ot_p2m_diag
4009 SUBROUTINE qs_ot_p2m_diag_complex(qs_ot_env)
4012 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_p2m_diag_complex'
4014 INTEGER :: col, col_offset, col_size, handle, i, j, &
4015 k, row, row_offset, row_size
4016 REAL(
dp),
DIMENSION(:, :),
POINTER :: block
4017 REAL(kind=
dp) :: a, b
4020 CALL timeset(routinen, handle)
4023 CALL cp_dbcsr_heevd(matrix_re=qs_ot_env%matrix_p, matrix_im=qs_ot_env%matrix_p_im, &
4024 eigenvectors_re=qs_ot_env%matrix_r, eigenvectors_im=qs_ot_env%matrix_r_im, &
4025 eigenvalues=qs_ot_env%evals, para_env=qs_ot_env%para_env, &
4026 blacs_env=qs_ot_env%blacs_env)
4028 qs_ot_env%evals(i) = max(0.0_dp, qs_ot_env%evals(i))
4032 qs_ot_env%dum(i) = cos(sqrt(qs_ot_env%evals(i)))
4034 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
4035 CALL dbcsr_copy(qs_ot_env%matrix_buf1_im, qs_ot_env%matrix_r_im)
4038 CALL qs_ot_complex_multiply(
'N',
'C', qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf1_im, &
4039 qs_ot_env%matrix_r, qs_ot_env%matrix_r_im, &
4040 qs_ot_env%matrix_cosp, qs_ot_env%matrix_cosp_im, &
4041 qs_ot_env%matrix_buf2)
4044 qs_ot_env%dum(i) = qs_ot_sinc(sqrt(qs_ot_env%evals(i)))
4046 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
4047 CALL dbcsr_copy(qs_ot_env%matrix_buf1_im, qs_ot_env%matrix_r_im)
4050 CALL qs_ot_complex_multiply(
'N',
'C', qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf1_im, &
4051 qs_ot_env%matrix_r, qs_ot_env%matrix_r_im, &
4052 qs_ot_env%matrix_sinp, qs_ot_env%matrix_sinp_im, &
4053 qs_ot_env%matrix_buf2)
4055 CALL dbcsr_copy(qs_ot_env%matrix_cosp_b, qs_ot_env%matrix_cosp)
4059 row_size=row_size, col_size=col_size, &
4060 row_offset=row_offset, col_offset=col_offset)
4063 a = (sqrt(qs_ot_env%evals(row_offset + i - 1)) &
4064 - sqrt(qs_ot_env%evals(col_offset + j - 1)))/2.0_dp
4065 b = (sqrt(qs_ot_env%evals(row_offset + i - 1)) &
4066 + sqrt(qs_ot_env%evals(col_offset + j - 1)))/2.0_dp
4067 block(i, j) = -0.5_dp*qs_ot_sinc(a)*qs_ot_sinc(b)
4073 CALL dbcsr_copy(qs_ot_env%matrix_sinp_b, qs_ot_env%matrix_sinp)
4077 row_size=row_size, col_size=col_size, &
4078 row_offset=row_offset, col_offset=col_offset)
4081 a = sqrt(qs_ot_env%evals(row_offset + i - 1))
4082 b = sqrt(qs_ot_env%evals(col_offset + j - 1))
4083 block(i, j) = qs_ot_sincf(a, b)
4089 CALL timestop(handle)
4091 END SUBROUTINE qs_ot_p2m_diag_complex
4098 FUNCTION qs_ot_sinc(x)
4100 REAL(kind=
dp),
INTENT(IN) :: x
4101 REAL(kind=
dp) :: qs_ot_sinc
4103 REAL(kind=
dp),
PARAMETER :: q1 = 1.0_dp, q2 = -q1/(2.0_dp*3.0_dp), q3 = -q2/(4.0_dp*5.0_dp), &
4104 q4 = -q3/(6.0_dp*7.0_dp), q5 = -q4/(8.0_dp*9.0_dp), q6 = -q5/(10.0_dp*11.0_dp), &
4105 q7 = -q6/(12.0_dp*13.0_dp), q8 = -q7/(14.0_dp*15.0_dp), q9 = -q8/(16.0_dp*17.0_dp), &
4106 q10 = -q9/(18.0_dp*19.0_dp)
4110 IF (abs(x) > 0.5_dp)
THEN
4111 qs_ot_sinc = sin(x)/x
4114 qs_ot_sinc = q1 + y*(q2 + y*(q3 + y*(q4 + y*(q5 + y*(q6 + y*(q7 + y*(q8 + y*(q9 + y*(q10)))))))))
4116 END FUNCTION qs_ot_sinc
4124 FUNCTION qs_ot_sincf(xa, ya)
4126 REAL(kind=
dp),
INTENT(IN) :: xa, ya
4127 REAL(kind=
dp) :: qs_ot_sincf
4130 REAL(kind=
dp) :: a, b, rs, sf, x, xs, y, ybx, ybxs
4133 IF (xa < 0) cpabort(
"x is negative")
4134 IF (ya < 0) cpabort(
"y is negative")
4144 IF (x < 0.5_dp)
THEN
4146 qs_ot_sincf = 0.0_dp
4147 IF (x > 0.0_dp)
THEN
4153 sf = -1.0_dp/((1.0_dp + ybx)*6.0_dp)
4159 qs_ot_sincf = qs_ot_sincf + sf*rs*xs*(1.0_dp + ybxs)
4160 sf = -sf/(real((2*i + 2),
dp)*real((2*i + 3),
dp))
4167 IF (x - y > 0.1_dp)
THEN
4168 qs_ot_sincf = (qs_ot_sinc(x) - qs_ot_sinc(y))/((x + y)*(x - y))
4173 qs_ot_sincf = (qs_ot_sinc(b)*cos(a) - qs_ot_sinc(a)*cos(b))/(2*x*y)
4177 END FUNCTION qs_ot_sincf
arnoldi iteration using dbcsr
subroutine, public arnoldi_extremal(matrix_a, max_ev, min_ev, converged, threshold, max_iter)
simple wrapper to estimate extremal eigenvalues with arnoldi, using the old lanczos interface this hi...
subroutine, public dbcsr_transposed(transposed, normal, shallow_data_copy, transpose_distribution, use_distribution)
...
subroutine, public dbcsr_release_p(matrix)
...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_reserve_blocks(matrix, rows, cols)
...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
subroutine, public dbcsr_filter(matrix, eps)
...
real(kind=dp) function, public dbcsr_get_occupation(matrix)
...
subroutine, public dbcsr_finalize(matrix)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_cholesky_decompose(matrix, n, para_env, blacs_env)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
subroutine, public cp_dbcsr_cholesky_restore(matrix, neig, matrixb, matrixout, op, pos, transa, para_env, blacs_env)
...
subroutine, public cp_dbcsr_cholesky_invert(matrix, n, para_env, blacs_env, uplo_to_full)
used to replace the cholesky decomposition by the inverse
real(dp) function, public dbcsr_gershgorin_norm(matrix)
Compute the gershgorin norm of a dbcsr matrix.
subroutine, public dbcsr_add_on_diag(matrix, alpha)
Adds the given scalar to the diagonal of the matrix. Reserves any missing diagonal blocks.
real(dp) function, public dbcsr_frobenius_norm(matrix)
Compute the frobenius norm of a dbcsr matrix.
subroutine, public dbcsr_hadamard_product(matrix_a, matrix_b, matrix_c)
Hadamard product: C = A . B (C needs to be different from A and B).
subroutine, public dbcsr_scale_by_vector(matrix, alpha, side)
Scales the rows/columns of given matrix.
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_heevd(matrix_re, matrix_im, eigenvectors_re, eigenvectors_im, eigenvalues, para_env, blacs_env)
...
subroutine, public cp_dbcsr_syevd(matrix, eigenvectors, eigenvalues, para_env, blacs_env)
...
Defines the basic variable types.
integer, parameter, public dp
Collection of simple mathematical functions and subroutines.
subroutine, public diag_complex(matrix, eigenvectors, eigenvalues)
Diagonalizes a local complex Hermitian matrix using LAPACK. Based on cp_cfm_heevd.
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Interface to the message passing library MPI.
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public qs_ot_get_derivative_ref_complex(matrix_hc, matrix_hc_im, qs_ot_env, matrix_hc_rotation, matrix_hc_rotation_im)
complex k-point REF derivative dE/dX from H(k)C(k), S(k)C(k), and C(k)
subroutine, public qs_ot_get_p(matrix_x, matrix_sx, qs_ot_env)
computes p=x*S*x and the matrix functionals related matrices
subroutine, public qs_ot_density_secant_hessian(density_step, hamiltonian_step, density_modes, correction, valid, density_norm_sq, response_work)
project a self-adjoint density/Hamiltonian secant onto density-response modes
subroutine, public qs_ot_get_orbitals_ref_complex(matrix_c, matrix_c_im, matrix_s, matrix_s_im, qs_ot_env, qs_ot_env1)
update complex REF k-point orbitals and their S(k)C(k) images
subroutine, public qs_ot_symmetric_abs_solve(matrix, rhs, solution, valid, relative_floor)
apply a positive spectral inverse of a real symmetric response matrix
subroutine, public qs_ot_generate_rotation_complex(qs_ot_env)
computes U=exp(A) for the complex anti-Hermitian generator A=rot_mat_x+i*rot_mat_x_im
pure subroutine, public qs_ot_symmetric_sr1_update(matrix, step, response, updated_matrix, valid, relative_tolerance)
add one accepted symmetric response secant to a reference Hessian
subroutine, public qs_ot_fixed_n_projector_frechet(chc, dchc, occupation, kpoint_weight, response_weight, fixed_n_weight_sum, projector_derivative, density_factor)
fixed-N Frechet derivative of a smooth occupation projector
subroutine, public qs_ot_fixed_n_schur_block(rotation_hessian, rayleigh_response, response_weight, rotation_gradient, energy_gradient, schur_block, coupling_vector, schur_rhs)
local block of the fixed-N rotation/energy Schur complement
subroutine, public qs_ot_finite_rotation_response(chc, rotation_generator, occupation, kpoint_weight, rotation_gradient, rotation_hessian, rayleigh_response, difference_step)
finite complex REF rotation Hessian and Rayleigh-energy response
pure subroutine, public qs_ot_fixed_n_energy_gradient(rayleigh_energy, energy_coordinate, response_weight, fixed_n_weight_sum, fixed_n_weighted_residual, gradient)
fixed-N Mermin gradient in auxiliary-energy coordinates
real(kind=dp) function, public qs_ot_antihermitian_spectral_norm(rotation_generator)
spectral norm of a dense anti-Hermitian rotation generator
subroutine, public qs_ot_get_derivative_complex(matrix_hc, matrix_hc_im, qs_ot_env, matrix_hc_rotation, matrix_hc_rotation_im)
finite complex STRICT derivative, projected onto C0^H*S*X=0
subroutine, public qs_ot_rot_mat_derivative_complex(qs_ot_env)
pull the complex dE/dU covector back to the anti-Hermitian generator using the adjoint Frechet deriva...
subroutine, public qs_ot_projected_response_update(reference_hessian, response_correction, coefficients, valid, projected_gradient, relative_floor)
update a baseline response direction in a small positive physical-response subspace
pure subroutine, public qs_ot_fixed_n_energy_hessian(response_weight, fixed_n_weight_sum, hessian)
dense fixed-N occupation Hessian in auxiliary-energy coordinates
subroutine, public qs_ot_prepare_complex_tangent_metric(qs_ot_env, preconditioner_rejected)
Prepare the inverse metric used to project a complex STRICT gradient. An unusable preconditioner is d...
subroutine, public qs_ot_density_secant_orbital_overlaps(overlap_start_current, occupation_start, occupation_current, hamiltonian_step_start, hamiltonian_step_current, density_modes, kpoint_weight, density_norm_sq, response_work, density_overlap, response_overlap, valid)
project a physical density/Hamiltonian secant between moving orbital subspaces
pure complex(kind=dp) function, public qs_ot_complex_exp_frechet_kernel(e1, e2)
Frechet divided-difference kernel for exp(-i*evals).
subroutine, public qs_ot_get_derivative_ref(matrix_hc, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
...
subroutine, public qs_ot_apply_complex_frechet_dbcsr(evals, inner_deriv_re, inner_deriv_im, outer_deriv_re, outer_deriv_im, adjoint)
apply the complex exponential Frechet kernel to sparse DBCSR Re/Im matrices
subroutine, public qs_ot_get_orbitals(matrix_c, matrix_x, qs_ot_env)
c=(c0*cos(p^0.5)+x*sin(p^0.5)*p^(-0.5)) x rot_mat_u this assumes that x is already ortho to S*C0,...
subroutine, public qs_ot_density_secant_projected_hessian(density_norm_sq, response_work, density_overlap, response_overlap, correction, valid, secant_mode, secant_position)
form a projected self-adjoint Hxc response from distributed density-space overlaps
subroutine, public qs_ot_rot_mat_derivative(qs_ot_env)
computes the derivative fields with respect to rot_mat_x
pure real(kind=dp) function, public qs_ot_fixed_n_response_mu_shift(weighted_energy_response, local_curvature_sum, fixed_n_curvature_sum)
chemical-potential response for one fixed-electron-number group
subroutine, public qs_ot_get_orbitals_ref(matrix_c, matrix_s, matrix_x, matrix_sx, matrix_gx_old, matrix_dx, qs_ot_env, qs_ot_env1)
...
subroutine, public qs_ot_get_derivative(matrix_hc, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
this routines computes dE/dx=dx, with dx ortho to sc0 needs dE/dC=hc,C0,X,SX,p if preconditioned it w...
subroutine, public qs_ot_new_preconditioner(qs_ot_env, preconditioner)
gets ready to use the preconditioner/ or renew the preconditioner only keeps a pointer to the precond...
subroutine, public qs_ot_fixed_n_multigroup_schur_block(rotation_hessian, rayleigh_response, response_weight, response_group, rotation_gradient, energy_gradient, schur_block, coupling_matrix, schur_rhs)
eliminate spin-resolved auxiliary energies while retaining every fixed-N constraint
subroutine, public qs_ot_density_tangent(rotation_generator, occupation, kpoint_weight, rotation_step, weighted_occupation_step, density_tangent, difference_step)
finite-chart density tangent for coupled complex rotations and fixed-N occupations
subroutine, public qs_ot_generate_rotation(qs_ot_env)
computes the rotation matrix rot_mat_u that is associated to a given rot_mat_x using rot_mat_u=exp(ro...
subroutine, public qs_ot_get_p_complex(matrix_x, matrix_x_im, matrix_sx, matrix_sx_im, qs_ot_env)
compute P=X^H*S*X and the STRICT matrix functions for a complex K-point channel
subroutine, public qs_ot_get_orbitals_complex(matrix_c, matrix_c_im, matrix_s, matrix_s_im, qs_ot_env)
update complex K-point orbitals with the finite STRICT transformation