73#include "./base/base_uses.f90"
80 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_localization_methods'
85 COMPLEX(KIND=dp),
POINTER,
DIMENSION(:) :: c_array => null()
86 END TYPE set_c_1d_type
89 COMPLEX(KIND=dp),
POINTER,
DIMENSION(:, :) :: c_array => null()
90 END TYPE set_c_2d_type
103 INTEGER,
INTENT(IN) :: iterations
104 REAL(kind=
dp),
INTENT(IN) :: eps
105 LOGICAL,
INTENT(INOUT) :: converged
106 INTEGER,
INTENT(INOUT) :: sweeps
108 CHARACTER(len=*),
PARAMETER :: routinen =
'approx_l1_norm_sd'
109 INTEGER,
PARAMETER :: taylor_order = 100
110 REAL(kind=
dp),
PARAMETER :: alpha = 0.1_dp, f2_eps = 0.01_dp
112 INTEGER :: handle, i, istep, k, n, ncol_local, &
113 nrow_local, output_unit, p
114 REAL(kind=
dp) :: expfactor, f2, f2old, gnorm, tnorm
120 CALL timeset(routinen, handle)
122 NULLIFY (context, para_env, fm_struct_k_k)
127 nrow_local=nrow_local, ncol_local=ncol_local, &
128 para_env=para_env, context=context)
130 nrow_global=k, ncol_global=k)
138 IF (output_unit > 0)
THEN
139 WRITE (output_unit,
'(1X)')
140 WRITE (output_unit,
'(2X,A)')
'-----------------------------------------------------------------------------'
141 WRITE (output_unit,
'(A,I5)')
' Nbr iterations =', iterations
142 WRITE (output_unit,
'(A,E10.2)')
' eps convergence =', eps
143 WRITE (output_unit,
'(A,I5)')
' Max Taylor order =', taylor_order
144 WRITE (output_unit,
'(A,E10.2)')
' f2 eps =', f2_eps
145 WRITE (output_unit,
'(A,E10.2)')
' alpha =', alpha
146 WRITE (output_unit,
'(A)')
' iteration approx_l1_norm g_norm rel_err'
153 DO istep = 1, iterations
161 f2 = f2 + sqrt(c%local_data(i, p)**2 + f2_eps)
164 CALL c%matrix_struct%para_env%sum(f2)
170 ctmp%local_data(i, p) = c%local_data(i, p)/sqrt(c%local_data(i, p)**2 + f2_eps)
173 CALL parallel_gemm(
'T',
'N', k, k, n, 1.0_dp, ctmp, c, 0.0_dp, g)
192 IF (tnorm > 1.0e-10_dp)
THEN
195 DO i = 2, taylor_order
197 CALL parallel_gemm(
'N',
'N', k, k, k, 1.0_dp, g, gp1, 0.0_dp, gp2)
200 expfactor = expfactor/real(i, kind=
dp)
203 IF (tnorm*expfactor < 1.0e-10_dp)
EXIT
208 CALL parallel_gemm(
'N',
'N', n, k, k, 1.0_dp, c, u, 0.0_dp, ctmp)
212 IF (output_unit > 0)
THEN
213 WRITE (output_unit,
'(10X,I4,E18.10,2E10.2)') istep, f2, gnorm, abs((f2 - f2old)/f2)
218 IF (abs((f2 - f2old)/f2) <= eps .AND. istep > 1)
THEN
228 IF (output_unit > 0)
WRITE (output_unit,
'(A,E16.10)')
' sparseness function f2 = ', f2
237 CALL timestop(handle)
248 REAL(kind=
dp),
DIMENSION(:) :: weights
250 REAL(kind=
dp),
DIMENSION(3, 3) :: metric
252 cpassert(
ASSOCIATED(cell))
255 CALL dgemm(
'T',
'N', 3, 3, 3, 1._dp, cell%hmat(:, :), 3, cell%hmat(:, :), 3, 0.0_dp, metric(:, :), 3)
257 weights(1) = metric(1, 1) - metric(1, 2) - metric(1, 3)
258 weights(2) = metric(2, 2) - metric(1, 2) - metric(2, 3)
259 weights(3) = metric(3, 3) - metric(1, 3) - metric(2, 3)
260 weights(4) = metric(1, 2)
261 weights(5) = metric(1, 3)
262 weights(6) = metric(2, 3)
284 eps_localization, sweeps, out_each, target_time, start_time, restricted)
286 REAL(kind=
dp),
INTENT(IN) :: weights(:)
287 TYPE(
cp_fm_type),
INTENT(IN) :: zij(:, :), vectors
289 INTEGER,
INTENT(IN) :: max_iter
290 REAL(kind=
dp),
INTENT(IN) :: eps_localization
292 INTEGER,
INTENT(IN) :: out_each
293 REAL(
dp) :: target_time, start_time
294 INTEGER :: restricted
296 IF (para_env%num_pe == 1)
THEN
297 CALL jacobi_rotations_serial(weights, zij, vectors, max_iter, eps_localization, &
298 sweeps, out_each, restricted=restricted)
300 CALL jacobi_rot_para(weights, zij, vectors, para_env, max_iter, eps_localization, &
301 sweeps, out_each, target_time, start_time, restricted=restricted)
318 SUBROUTINE jacobi_rotations_serial(weights, zij, vectors, max_iter, eps_localization, sweeps, &
319 out_each, restricted)
320 REAL(kind=
dp),
INTENT(IN) :: weights(:)
321 TYPE(
cp_fm_type),
INTENT(IN) :: zij(:, :), vectors
322 INTEGER,
INTENT(IN) :: max_iter
323 REAL(kind=
dp),
INTENT(IN) :: eps_localization
325 INTEGER,
INTENT(IN) :: out_each
326 INTEGER :: restricted
328 CHARACTER(len=*),
PARAMETER :: routinen =
'jacobi_rotations_serial'
330 COMPLEX(KIND=dp),
POINTER :: mii(:), mij(:), mjj(:)
331 INTEGER :: dim2, handle, idim, istate, jstate, &
333 REAL(kind=
dp) :: ct, st, t1, t2, theta, tolerance
335 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: c_zij
338 CALL timeset(routinen, handle)
341 ALLOCATE (c_zij(dim2))
342 NULLIFY (mii, mij, mjj)
343 ALLOCATE (mii(dim2), mij(dim2), mjj(dim2))
352 c_zij(idim)%local_data = cmplx(zij(1, idim)%local_data, &
353 zij(2, idim)%local_data,
dp)
357 tolerance = 1.0e10_dp
361 IF (rmat%matrix_struct%para_env%is_source())
THEN
363 WRITE (unit_nr,
'(T4,A )')
" Localization by iterative Jacobi rotation"
366 IF (restricted > 0)
THEN
368 WRITE (unit_nr,
'(T4,A,I2,A )')
"JACOBI: for the ROKS method, the last ", restricted,
" orbitals DO NOT ROTATE"
369 nstate = nstate - restricted
373 DO WHILE (tolerance >= eps_localization .AND. sweeps < max_iter)
377 DO istate = 1, nstate
378 DO jstate = istate + 1, nstate
384 CALL get_angle(mii, mjj, mij, weights, theta)
387 CALL rotate_zij(istate, jstate, st, ct, c_zij)
389 CALL rotate_rmat(istate, jstate, st, ct, c_rmat)
393 CALL check_tolerance(c_zij, weights, tolerance)
396 IF (unit_nr > 0 .AND.
modulo(sweeps, out_each) == 0)
THEN
397 WRITE (unit_nr,
'(T4,A,I7,T30,A,E12.4,T60,A,F8.3)') &
398 "Iteration:", sweeps,
"Tolerance:", tolerance,
"Time:", t2 - t1
405 zij(1, idim)%local_data = real(c_zij(idim)%local_data,
dp)
406 zij(2, idim)%local_data = aimag(c_zij(idim)%local_data)
410 DEALLOCATE (mii, mij, mjj)
411 rmat%local_data = real(c_rmat%local_data,
dp)
418 CALL timestop(handle)
420 END SUBROUTINE jacobi_rotations_serial
434 SUBROUTINE jacobi_rotations_serial_1(weights, c_zij, max_iter, c_rmat, eps_localization, &
435 tol_out, jsweeps, out_each, c_zij_out, grad_final)
436 REAL(kind=
dp),
INTENT(IN) :: weights(:)
438 INTEGER,
INTENT(IN) :: max_iter
440 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_localization
441 REAL(kind=
dp),
INTENT(OUT),
OPTIONAL :: tol_out
442 INTEGER,
INTENT(OUT),
OPTIONAL :: jsweeps
443 INTEGER,
INTENT(IN),
OPTIONAL :: out_each
444 TYPE(
cp_cfm_type),
INTENT(IN),
OPTIONAL :: c_zij_out(:)
445 TYPE(
cp_fm_type),
INTENT(OUT),
OPTIONAL,
POINTER :: grad_final
447 CHARACTER(len=*),
PARAMETER :: routinen =
'jacobi_rotations_serial_1'
449 COMPLEX(KIND=dp) :: mzii
450 COMPLEX(KIND=dp),
POINTER :: mii(:), mij(:), mjj(:)
451 INTEGER :: dim2, handle, idim, istate, jstate, &
452 nstate, sweeps, unit_nr
453 REAL(kind=
dp) :: alpha, avg_spread_ii, ct, spread_ii, st, &
454 sum_spread_ii, t1, t2, theta, tolerance
458 CALL timeset(routinen, handle)
461 NULLIFY (mii, mij, mjj)
462 ALLOCATE (mii(dim2), mij(dim2), mjj(dim2))
464 ALLOCATE (c_zij_local(dim2))
466 CALL cp_cfm_set_all(c_rmat_local, (0.0_dp, 0.0_dp), (1.0_dp, 0.0_dp))
468 CALL cp_cfm_create(c_zij_local(idim), c_zij(idim)%matrix_struct)
469 c_zij_local(idim)%local_data = c_zij(idim)%local_data
473 tolerance = 1.0e10_dp
475 IF (
PRESENT(grad_final))
CALL cp_fm_set_all(grad_final, 0.0_dp)
478 IF (
PRESENT(out_each))
THEN
480 IF (c_rmat_local%matrix_struct%para_env%is_source())
THEN
485 alpha = alpha + weights(idim)
490 DO WHILE (sweeps < max_iter)
492 IF (
PRESENT(eps_localization))
THEN
493 IF (tolerance < eps_localization)
EXIT
497 DO istate = 1, nstate
498 DO jstate = istate + 1, nstate
504 CALL get_angle(mii, mjj, mij, weights, theta)
507 CALL rotate_zij(istate, jstate, st, ct, c_zij_local)
509 CALL rotate_rmat(istate, jstate, st, ct, c_rmat_local)
513 IF (
PRESENT(grad_final))
THEN
514 CALL check_tolerance(c_zij_local, weights, tolerance, grad=grad_final)
516 CALL check_tolerance(c_zij_local, weights, tolerance)
518 IF (
PRESENT(tol_out)) tol_out = tolerance
520 IF (
PRESENT(out_each))
THEN
522 IF (unit_nr > 0 .AND.
modulo(sweeps, out_each) == 0)
THEN
523 sum_spread_ii = 0.0_dp
524 DO istate = 1, nstate
528 spread_ii = spread_ii + weights(idim)* &
531 sum_spread_ii = sum_spread_ii + spread_ii
533 sum_spread_ii = alpha*nstate/
twopi/
twopi - sum_spread_ii
534 avg_spread_ii = sum_spread_ii/nstate
535 WRITE (unit_nr,
'(T4,A,T26,A,T48,A,T64,A)') &
536 "Iteration",
"Avg. Spread_ii",
"Tolerance",
"Time"
537 WRITE (unit_nr,
'(T4,I7,T20,F20.10,T45,E12.4,T60,F8.3)') &
538 sweeps, avg_spread_ii, tolerance, t2 - t1
541 IF (
PRESENT(jsweeps)) jsweeps = sweeps
546 IF (
PRESENT(c_zij_out))
THEN
553 DEALLOCATE (mii, mij, mjj)
557 DEALLOCATE (c_zij_local)
560 CALL timestop(handle)
562 END SUBROUTINE jacobi_rotations_serial_1
581 iter, out_each, nextra, do_cg, nmo, vectors_2, mos_guess)
583 REAL(kind=
dp),
INTENT(IN) :: weights(:)
584 TYPE(
cp_fm_type),
INTENT(IN) :: zij(:, :), vectors
585 INTEGER,
INTENT(IN) :: max_iter
586 REAL(kind=
dp),
INTENT(IN) :: eps_localization
588 INTEGER,
INTENT(IN) :: out_each, nextra
589 LOGICAL,
INTENT(IN) :: do_cg
590 INTEGER,
INTENT(IN),
OPTIONAL :: nmo
591 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: vectors_2, mos_guess
593 CHARACTER(len=*),
PARAMETER :: routinen =
'jacobi_cg_edf_ls'
594 COMPLEX(KIND=dp),
PARAMETER :: cone = (1.0_dp, 0.0_dp), &
595 czero = (0.0_dp, 0.0_dp)
596 REAL(kind=
dp),
PARAMETER :: gold_sec = 0.3819_dp
598 COMPLEX(KIND=dp) :: cnorm2_gct, cnorm2_gct_cross, mzii
599 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: tmp_cmat
600 COMPLEX(KIND=dp),
DIMENSION(:),
POINTER :: arr_zii
601 COMPLEX(KIND=dp),
DIMENSION(:, :),
POINTER :: matrix_zii
602 INTEGER :: dim2, handle, icinit, idim, istate, line_search_count, line_searches, lsl, lsm, &
603 lsr, miniter, nao, ndummy, nocc, norextra, northo, nstate, unit_nr
604 INTEGER,
DIMENSION(1) :: iloc
605 LOGICAL :: do_cinit_mo, do_cinit_random, &
606 do_u_guess_mo, new_direction
607 REAL(kind=
dp) :: alpha, avg_spread_ii, beta, beta_pr, ds, ds_min, mintol, norm, norm2_gct, &
608 norm2_gct_cross, norm2_old, spread_ii, spread_sum, sum_spread_ii, t1, tol, tolc, weight
609 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: sum_spread
610 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: tmp_mat, tmp_mat_1
611 REAL(kind=
dp),
DIMENSION(50) :: energy, pos
612 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tmp_arr
614 TYPE(
cp_cfm_type) :: c_tilde, ctrans_lambda, gct_old, &
615 grad_ctilde, skc, tmp_cfm, tmp_cfm_1, &
616 tmp_cfm_2, u, ul, v, vl, zdiag
617 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: c_zij, zij_0
619 TYPE(
cp_fm_type) :: id_nextra, matrix_u, matrix_v, &
620 matrix_v_all, rmat, tmp_fm, vectors_all
622 CALL timeset(routinen, handle)
626 NULLIFY (matrix_zii, arr_zii)
627 NULLIFY (tmp_fm_struct)
630 ALLOCATE (c_zij(dim2))
634 ALLOCATE (sum_spread(nstate))
635 ALLOCATE (matrix_zii(nstate, dim2))
641 alpha = alpha + weights(idim)
643 c_zij(idim)%local_data = cmplx(zij(1, idim)%local_data, &
644 zij(2, idim)%local_data,
dp)
647 ALLOCATE (zij_0(dim2))
657 IF (
PRESENT(mos_guess))
THEN
658 do_cinit_random = .false.
662 do_cinit_random = .true.
663 do_cinit_mo = .false.
667 IF (do_cinit_random)
THEN
669 do_u_guess_mo = .false.
670 ELSE IF (do_cinit_mo)
THEN
672 do_u_guess_mo = .true.
675 nocc = nstate - nextra
677 norextra = nmo - nstate
680 ALLOCATE (tmp_cmat(nstate, nstate))
682 para_env=para_env, context=context)
690 DEALLOCATE (tmp_cmat)
693 para_env=para_env, context=context)
703 para_env=para_env, context=context)
708 ALLOCATE (arr_zii(nstate))
711 para_env=para_env, context=context)
722 para_env=para_env, context=context)
728 para_env=para_env, context=context)
736 para_env=para_env, context=context)
742 para_env=para_env, context=context)
745 ALLOCATE (tmp_mat(nao, nstate))
749 ALLOCATE (tmp_mat(nao, norextra))
760 CALL ortho_vectors(tmp_fm)
761 c_tilde%local_data = tmp_fm%local_data
763 ALLOCATE (tmp_cmat(northo, nextra))
766 DEALLOCATE (tmp_cmat)
768 CALL parallel_gemm(
"T",
"N", nmo, ndummy, nao, 1.0_dp, vectors_all, mos_guess, 0.0_dp, matrix_v_all)
769 ALLOCATE (tmp_arr(nmo))
770 ALLOCATE (tmp_mat(nmo, ndummy))
771 ALLOCATE (tmp_mat_1(nmo, nstate))
774 DO istate = 1, ndummy
775 tmp_arr(:) = tmp_mat(:, istate)
776 norm = norm2(tmp_arr)
777 tmp_arr(:) = tmp_arr(:)/norm
778 tmp_mat(:, istate) = tmp_arr(:)
783 DEALLOCATE (tmp_arr, tmp_mat, tmp_mat_1)
785 ALLOCATE (tmp_mat(northo, ndummy))
786 ALLOCATE (tmp_mat_1(northo, nextra))
788 ALLOCATE (tmp_arr(ndummy))
790 DO istate = 1, ndummy
791 tmp_arr(istate) = norm2(tmp_mat(:, istate))
794 DO istate = 1, nextra
795 iloc = maxloc(tmp_arr)
796 tmp_mat_1(:, istate) = tmp_mat(:, iloc(1))
797 tmp_arr(iloc(1)) = 0.0_dp
800 DEALLOCATE (tmp_arr, tmp_mat)
803 para_env=para_env, context=context)
807 DEALLOCATE (tmp_mat_1)
808 CALL ortho_vectors(tmp_fm)
812 IF (do_u_guess_mo)
THEN
813 ALLOCATE (tmp_cmat(nocc, nstate))
816 DEALLOCATE (tmp_cmat)
817 ALLOCATE (tmp_cmat(northo, nstate))
820 DEALLOCATE (tmp_cmat)
821 CALL parallel_gemm(
"C",
"N", nextra, nstate, northo, cone, c_tilde, vl, czero, ul)
822 ALLOCATE (tmp_cmat(nextra, nstate))
825 DEALLOCATE (tmp_cmat)
827 tmp_fm%local_data = real(u%local_data, kind=
dp)
828 CALL ortho_vectors(tmp_fm)
834 ALLOCATE (tmp_cmat(nocc, nstate))
837 DEALLOCATE (tmp_cmat)
838 ALLOCATE (tmp_cmat(nextra, nstate))
841 DEALLOCATE (tmp_cmat)
842 CALL parallel_gemm(
"N",
"N", northo, nstate, nextra, cone, c_tilde, ul, czero, vl)
843 ALLOCATE (tmp_cmat(northo, nstate))
846 DEALLOCATE (tmp_cmat)
858 IF (rmat%matrix_struct%para_env%is_source())
THEN
860 WRITE (unit_nr,
'(T4,A )')
" Localization by combined Jacobi rotations and Non-Linear Conjugate Gradient"
863 norm2_old = 1.0e30_dp
865 new_direction = .true.
868 line_search_count = 0
877 DO WHILE (iter < max_iter)
886 IF (para_env%num_pe == 1)
THEN
887 CALL jacobi_rotations_serial_1(weights, c_zij, 1, tmp_cfm_2, tol_out=tol)
889 CALL jacobi_rot_para_1(weights, c_zij, para_env, 1, tmp_cfm_2, tol_out=tol)
891 CALL parallel_gemm(
'N',
'N', nstate, nstate, nstate, cone, u, tmp_cfm_2, czero, tmp_cfm)
898 ALLOCATE (tmp_cmat(nextra, nstate))
901 DEALLOCATE (tmp_cmat)
905 tmp_fm%local_data = real(c_tilde%local_data, kind=
dp)
906 CALL ortho_vectors(tmp_fm)
910 ALLOCATE (tmp_cmat(nocc, nstate))
913 DEALLOCATE (tmp_cmat)
914 CALL parallel_gemm(
"N",
"N", northo, nstate, nextra, cone, c_tilde, ul, czero, vl)
915 ALLOCATE (tmp_cmat(northo, nstate))
918 DEALLOCATE (tmp_cmat)
922 IF (new_direction .AND. mod(line_searches, 20) == 5)
THEN
925 norm2_old = 1.0e30_dp
941 CALL parallel_gemm(
"N",
"N", ndummy, nstate, ndummy, cone, zij_0(idim), &
942 tmp_cfm, czero, tmp_cfm_1)
944 CALL parallel_gemm(
"C",
"N", nstate, nstate, ndummy, cone, tmp_cfm, tmp_cfm_1, &
950 DO istate = 1, nstate
954 spread_ii = spread_ii + weights(idim)* &
956 matrix_zii(istate, idim) = mzii
959 sum_spread(istate) = spread_ii
961 CALL c_zij(1)%matrix_struct%para_env%sum(spread_ii)
972 ALLOCATE (tmp_cmat(northo, nstate))
974 weight = weights(idim)
975 arr_zii = matrix_zii(:, idim)
978 zij_0(idim), v, czero, tmp_cfm)
982 CALL parallel_gemm(
"N",
"C", nmo, nstate, nstate, cone, tmp_cfm, &
990 zij_0(idim), v, czero, tmp_cfm)
995 CALL parallel_gemm(
"N",
"C", nmo, nstate, nstate, cone, tmp_cfm, &
1003 DEALLOCATE (tmp_cmat)
1004 ALLOCATE (tmp_cmat(northo, nextra))
1006 northo, nextra, .false.)
1009 DEALLOCATE (tmp_cmat)
1011 CALL parallel_gemm(
"C",
"N", nextra, nextra, northo, cone, c_tilde, grad_ctilde, czero, ctrans_lambda)
1014 CALL parallel_gemm(
"N",
"N", northo, nextra, nextra, -cone, c_tilde, ctrans_lambda, cone, grad_ctilde)
1018 IF (nextra > 0)
THEN
1029 IF (nextra > 0)
THEN
1031 IF (new_direction)
THEN
1032 line_searches = line_searches + 1
1033 IF (mintol > tol)
THEN
1038 IF (unit_nr > 0 .AND.
modulo(iter, out_each) == 0)
THEN
1039 sum_spread_ii = alpha*nstate/
twopi/
twopi - spread_sum
1040 avg_spread_ii = sum_spread_ii/nstate
1041 WRITE (unit_nr,
'(T4,A,T26,A,T48,A)') &
1042 "Iteration",
"Avg. Spread_ii",
"Tolerance"
1043 WRITE (unit_nr,
'(T4,I7,T20,F20.10,T45,E12.4)') &
1044 iter, avg_spread_ii, tol
1047 IF (tol < eps_localization)
EXIT
1051 cnorm2_gct_cross = czero
1052 CALL cp_cfm_trace(grad_ctilde, gct_old, cnorm2_gct_cross)
1053 norm2_gct_cross = real(cnorm2_gct_cross, kind=
dp)
1054 gct_old%local_data = grad_ctilde%local_data
1056 norm2_gct = real(cnorm2_gct, kind=
dp)
1058 beta_pr = (norm2_gct - norm2_gct_cross)/norm2_old
1059 norm2_old = norm2_gct
1060 beta = max(0.0_dp, beta_pr)
1066 norm2_gct_cross = real(cnorm2_gct_cross, kind=
dp)
1067 IF (norm2_gct_cross <= 0.0_dp)
THEN
1073 line_search_count = 0
1076 line_search_count = line_search_count + 1
1078 energy(line_search_count) = spread_sum
1081 new_direction = .false.
1082 IF (line_search_count == 1)
THEN
1087 pos(2) = ds_min/gold_sec
1090 IF (line_search_count == 50)
THEN
1091 IF (abs(energy(line_search_count) - energy(line_search_count - 1)) < 1.0e-4_dp)
THEN
1092 cpwarn(
"Line search failed to converge properly")
1094 new_direction = .true.
1095 ds = pos(line_search_count)
1096 line_search_count = 0
1098 cpabort(
"No. of line searches exceeds 50")
1102 IF (energy(line_search_count - 1) > energy(line_search_count))
THEN
1103 lsr = line_search_count
1104 pos(line_search_count + 1) = pos(lsm) + (pos(lsr) - pos(lsm))*gold_sec
1107 lsm = line_search_count
1108 pos(line_search_count + 1) = pos(line_search_count)/gold_sec
1111 IF (pos(line_search_count) < pos(lsm))
THEN
1112 IF (energy(line_search_count) > energy(lsm))
THEN
1114 lsm = line_search_count
1116 lsl = line_search_count
1119 IF (energy(line_search_count) > energy(lsm))
THEN
1121 lsm = line_search_count
1123 lsr = line_search_count
1126 IF (pos(lsr) - pos(lsm) > pos(lsm) - pos(lsl))
THEN
1127 pos(line_search_count + 1) = pos(lsm) + gold_sec*(pos(lsr) - pos(lsm))
1129 pos(line_search_count + 1) = pos(lsl) + gold_sec*(pos(lsm) - pos(lsl))
1131 IF ((pos(lsr) - pos(lsl)) < 1.0e-3_dp*pos(lsr))
THEN
1132 new_direction = .true.
1137 ds = pos(line_search_count + 1) - pos(line_search_count)
1139 IF ((abs(ds) < 1.0e-10_dp) .AND. (lsl == 1))
THEN
1140 new_direction = .true.
1141 ds_min = 0.5_dp/alpha
1142 ELSE IF (abs(ds) > 10.0_dp)
THEN
1143 new_direction = .true.
1144 ds_min = 0.5_dp/alpha
1146 ds_min = pos(line_search_count + 1)
1153 IF (mintol > tol)
THEN
1157 IF (unit_nr > 0 .AND.
modulo(iter, out_each) == 0)
THEN
1158 sum_spread_ii = alpha*nstate/
twopi/
twopi - spread_sum
1159 avg_spread_ii = sum_spread_ii/nstate
1160 WRITE (unit_nr,
'(T4,A,T26,A,T48,A)') &
1161 "Iteration",
"Avg. Spread_ii",
"Tolerance"
1162 WRITE (unit_nr,
'(T4,I7,T20,F20.10,T45,E12.4)') &
1163 iter, avg_spread_ii, tol
1166 IF (tol < eps_localization)
EXIT
1171 IF ((unit_nr > 0) .AND. (iter == max_iter))
THEN
1172 WRITE (unit_nr,
'(T4,A,T4,A)')
"Min. Itr.",
"Min. Tol."
1173 WRITE (unit_nr,
'(T4,I7,T4,E12.4)') miniter, mintol
1179 IF (nextra > 0)
THEN
1180 rmat%local_data = real(v%local_data, kind=
dp)
1181 CALL rotate_orbitals_edf(rmat, vectors_all, vectors)
1196 DEALLOCATE (arr_zii)
1198 rmat%local_data = matrix_u%local_data
1207 zij(1, idim)%local_data = real(c_zij(idim)%local_data,
dp)
1208 zij(2, idim)%local_data = aimag(c_zij(idim)%local_data)
1215 DEALLOCATE (matrix_zii, sum_spread)
1217 CALL timestop(handle)
1225 SUBROUTINE ortho_vectors(vmatrix)
1229 CHARACTER(LEN=*),
PARAMETER :: routinen =
'ortho_vectors'
1231 INTEGER :: handle, n, ncol
1235 CALL timeset(routinen, handle)
1237 NULLIFY (fm_struct_tmp)
1239 CALL cp_fm_get_info(matrix=vmatrix, nrow_global=n, ncol_global=ncol)
1242 para_env=vmatrix%matrix_struct%para_env, &
1243 context=vmatrix%matrix_struct%context)
1244 CALL cp_fm_create(overlap_vv, fm_struct_tmp,
"overlap_vv")
1247 CALL parallel_gemm(
'T',
'N', ncol, ncol, n, 1.0_dp, vmatrix, vmatrix, 0.0_dp, overlap_vv)
1253 CALL timestop(handle)
1255 END SUBROUTINE ortho_vectors
1265 SUBROUTINE rotate_zij(istate, jstate, st, ct, zij)
1266 INTEGER,
INTENT(IN) :: istate, jstate
1267 REAL(kind=
dp),
INTENT(IN) :: st, ct
1274 DO id = 1,
SIZE(zij, 1)
1279 END SUBROUTINE rotate_zij
1288 SUBROUTINE rotate_rmat(istate, jstate, st, ct, rmat)
1289 INTEGER,
INTENT(IN) :: istate, jstate
1290 REAL(kind=
dp),
INTENT(IN) :: st, ct
1295 END SUBROUTINE rotate_rmat
1306 SUBROUTINE get_angle(mii, mjj, mij, weights, theta, grad_ij, step)
1307 COMPLEX(KIND=dp),
POINTER :: mii(:), mjj(:), mij(:)
1308 REAL(kind=
dp),
INTENT(IN) :: weights(:)
1309 REAL(kind=
dp),
INTENT(OUT) :: theta
1310 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: grad_ij, step
1312 COMPLEX(KIND=dp) :: z11, z12, z22
1313 INTEGER :: dim_m, idim
1314 REAL(kind=
dp) :: a12, b12, d2, ratio
1323 a12 = a12 + weights(idim)*real(conjg(z12)*(z11 - z22), kind=
dp)
1324 b12 = b12 + weights(idim)*real((z12*conjg(z12) - &
1325 0.25_dp*(z11 - z22)*(conjg(z11) - conjg(z22))), kind=
dp)
1327 IF (abs(b12) > 1.e-10_dp)
THEN
1329 theta = 0.25_dp*atan(ratio)
1330 ELSE IF (abs(b12) < 1.e-10_dp)
THEN
1336 IF (
PRESENT(grad_ij)) theta = theta + step*grad_ij
1338 d2 = a12*sin(4._dp*theta) - b12*cos(4._dp*theta)
1339 IF (d2 <= 0._dp)
THEN
1340 IF (theta > 0.0_dp)
THEN
1341 theta = theta - 0.25_dp*
pi
1343 theta = theta + 0.25_dp*
pi
1346 END SUBROUTINE get_angle
1354 SUBROUTINE check_tolerance(zij, weights, tolerance, grad)
1356 REAL(kind=
dp),
INTENT(IN) :: weights(:)
1357 REAL(kind=
dp),
INTENT(OUT) :: tolerance
1358 TYPE(
cp_fm_type),
INTENT(OUT),
OPTIONAL :: grad
1360 CHARACTER(len=*),
PARAMETER :: routinen =
'check_tolerance'
1365 CALL timeset(routinen, handle)
1371 CALL grad_at_0(zij, weights, force)
1376 CALL timestop(handle)
1378 END SUBROUTINE check_tolerance
1386 TYPE(
cp_fm_type),
INTENT(IN) :: rmat, vectors
1393 CALL parallel_gemm(
"N",
"N", n, k, k, 1.0_dp, vectors, rmat, 0.0_dp, wf)
1403 SUBROUTINE rotate_orbitals_cfm(rmat, vectors)
1414 END SUBROUTINE rotate_orbitals_cfm
1422 SUBROUTINE rotate_orbitals_edf(rmat, vec_all, vectors)
1423 TYPE(
cp_fm_type),
INTENT(IN) :: rmat, vec_all, vectors
1432 CALL parallel_gemm(
"N",
"N", n, l, k, 1.0_dp, vec_all, rmat, 0.0_dp, wf)
1435 END SUBROUTINE rotate_orbitals_edf
1443 SUBROUTINE gradsq_at_0(diag, weights, matrix, ndim)
1444 COMPLEX(KIND=dp),
DIMENSION(:, :),
POINTER :: diag
1445 REAL(kind=
dp),
INTENT(IN) :: weights(:)
1447 INTEGER,
INTENT(IN) :: ndim
1449 COMPLEX(KIND=dp) :: zii, zjj
1450 INTEGER :: idim, istate, jstate, ncol_local, &
1451 nrow_global, nrow_local
1452 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1453 REAL(kind=
dp) :: gradsq_ij
1456 ncol_local=ncol_local, nrow_global=nrow_global, &
1457 row_indices=row_indices, col_indices=col_indices)
1459 DO istate = 1, nrow_local
1460 DO jstate = 1, ncol_local
1464 zii = diag(row_indices(istate), idim)
1465 zjj = diag(col_indices(jstate), idim)
1466 gradsq_ij = gradsq_ij + weights(idim)* &
1467 4.0_dp*real((conjg(zii)*zii + conjg(zjj)*zjj), kind=
dp)
1469 matrix%local_data(istate, jstate) = gradsq_ij
1472 END SUBROUTINE gradsq_at_0
1479 SUBROUTINE grad_at_0(matrix_p, weights, matrix)
1481 REAL(kind=
dp),
INTENT(IN) :: weights(:)
1484 COMPLEX(KIND=dp) :: zii, zij, zjj
1485 COMPLEX(KIND=dp),
DIMENSION(:, :),
POINTER :: diag
1486 INTEGER :: dim_m, idim, istate, jstate, ncol_local, &
1487 nrow_global, nrow_local
1488 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1489 REAL(kind=
dp) :: grad_ij
1493 ncol_local=ncol_local, nrow_global=nrow_global, &
1494 row_indices=row_indices, col_indices=col_indices)
1495 dim_m =
SIZE(matrix_p, 1)
1496 ALLOCATE (diag(nrow_global, dim_m))
1499 DO istate = 1, nrow_global
1504 DO istate = 1, nrow_local
1505 DO jstate = 1, ncol_local
1509 zii = diag(row_indices(istate), idim)
1510 zjj = diag(col_indices(jstate), idim)
1511 zij = matrix_p(idim)%local_data(istate, jstate)
1512 grad_ij = grad_ij + weights(idim)* &
1513 REAL(4.0_dp*conjg(zij)*(zjj - zii),
dp)
1515 matrix%local_data(istate, jstate) = grad_ij
1519 END SUBROUTINE grad_at_0
1529 SUBROUTINE check_tolerance_new(weights, zij, tolerance, value)
1530 REAL(kind=
dp),
INTENT(IN) :: weights(:)
1532 REAL(kind=
dp) :: tolerance,
value
1534 COMPLEX(KIND=dp) :: kii, kij, kjj
1535 COMPLEX(KIND=dp),
DIMENSION(:, :),
POINTER :: diag
1536 INTEGER :: idim, istate, jstate, ncol_local, &
1537 nrow_global, nrow_local
1538 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1539 REAL(kind=
dp) :: grad_ij, ra, rb
1543 ncol_local=ncol_local, nrow_global=nrow_global, &
1544 row_indices=row_indices, col_indices=col_indices)
1545 ALLOCATE (diag(nrow_global,
SIZE(zij, 2)))
1547 DO idim = 1,
SIZE(zij, 2)
1548 DO istate = 1, nrow_global
1551 diag(istate, idim) = cmplx(ra, rb,
dp)
1552 value =
value + weights(idim) - weights(idim)*abs(diag(istate, idim))**2
1556 DO istate = 1, nrow_local
1557 DO jstate = 1, ncol_local
1559 DO idim = 1,
SIZE(zij, 2)
1560 kii = diag(row_indices(istate), idim)
1561 kjj = diag(col_indices(jstate), idim)
1562 ra = zij(1, idim)%local_data(istate, jstate)
1563 rb = zij(2, idim)%local_data(istate, jstate)
1564 kij = cmplx(ra, rb,
dp)
1565 grad_ij = grad_ij + weights(idim)* &
1566 REAL(4.0_dp*conjg(kij)*(kjj - kii),
dp)
1568 tolerance = max(abs(grad_ij), tolerance)
1571 CALL zij(1, 1)%matrix_struct%para_env%max(tolerance)
1575 END SUBROUTINE check_tolerance_new
1591 SUBROUTINE crazy_rotations(weights, zij, vectors, max_iter, max_crazy_angle, crazy_scale, crazy_use_diag, &
1592 eps_localization, iterations, converged)
1593 REAL(kind=
dp),
INTENT(IN) :: weights(:)
1594 TYPE(
cp_fm_type),
INTENT(IN) :: zij(:, :), vectors
1595 INTEGER,
INTENT(IN) :: max_iter
1596 REAL(kind=
dp),
INTENT(IN) :: max_crazy_angle
1597 REAL(kind=
dp) :: crazy_scale
1598 LOGICAL :: crazy_use_diag
1599 REAL(kind=
dp),
INTENT(IN) :: eps_localization
1600 INTEGER :: iterations
1601 LOGICAL,
INTENT(out),
OPTIONAL :: converged
1603 CHARACTER(len=*),
PARAMETER :: routinen =
'crazy_rotations'
1604 COMPLEX(KIND=dp),
PARAMETER :: cone = (1.0_dp, 0.0_dp), &
1605 czero = (0.0_dp, 0.0_dp)
1607 COMPLEX(KIND=dp),
DIMENSION(:),
POINTER :: evals_exp
1608 COMPLEX(KIND=dp),
DIMENSION(:, :),
POINTER :: diag_z
1609 COMPLEX(KIND=dp),
POINTER :: mii(:), mij(:), mjj(:)
1610 INTEGER :: dim2, handle, i, icol, idim, irow, &
1611 method, ncol_global, ncol_local, &
1612 norder, nrow_global, nrow_local, &
1614 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1616 REAL(kind=
dp) :: eps_exp, limit_crazy_angle, maxeval, &
1617 norm, ra, rb, theta, tolerance,
value
1618 REAL(kind=
dp),
DIMENSION(:),
POINTER :: evals
1620 TYPE(
cp_fm_type) :: mat_r, mat_t, mat_theta, mat_u
1622 CALL timeset(routinen, handle)
1623 NULLIFY (row_indices, col_indices)
1625 ncol_global=ncol_global, &
1626 row_indices=row_indices, col_indices=col_indices, &
1627 nrow_local=nrow_local, ncol_local=ncol_local)
1629 limit_crazy_angle = max_crazy_angle
1631 NULLIFY (diag_z, evals, evals_exp, mii, mij, mjj)
1633 ALLOCATE (diag_z(nrow_global, dim2))
1634 ALLOCATE (evals(nrow_global))
1635 ALLOCATE (evals_exp(nrow_global))
1649 ALLOCATE (mii(dim2), mij(dim2), mjj(dim2))
1657 CALL parallel_gemm(
'N',
'N', nrow_global, nrow_global, nrow_global, 1.0_dp, zij(1, idim), mat_u, 0.0_dp, mat_t)
1658 CALL parallel_gemm(
'T',
'N', nrow_global, nrow_global, nrow_global, 1.0_dp, mat_u, mat_t, 0.0_dp, zij(1, idim))
1659 CALL parallel_gemm(
'N',
'N', nrow_global, nrow_global, nrow_global, 1.0_dp, zij(2, idim), mat_u, 0.0_dp, mat_t)
1660 CALL parallel_gemm(
'T',
'N', nrow_global, nrow_global, nrow_global, 1.0_dp, mat_u, mat_t, 0.0_dp, zij(2, idim))
1663 CALL parallel_gemm(
'N',
'N', nrow_global, nrow_global, nrow_global, 1.0_dp, mat_r, mat_u, 0.0_dp, mat_t)
1667 IF (cmat_a%matrix_struct%para_env%is_source())
THEN
1669 WRITE (unit_nr,
'(T2,A7,A6,1X,A20,A12,A12,A12)') &
1670 "CRAZY| ",
"Iter",
"value ",
"gradient",
"Max. eval",
"limit"
1677 iterations = iterations + 1
1679 DO i = 1, nrow_global
1682 diag_z(i, idim) = cmplx(ra, rb,
dp)
1685 DO irow = 1, nrow_local
1686 DO icol = 1, ncol_local
1688 ra = zij(1, idim)%local_data(irow, icol)
1689 rb = zij(2, idim)%local_data(irow, icol)
1690 mij(idim) = cmplx(ra, rb,
dp)
1691 mii(idim) = diag_z(row_indices(irow), idim)
1692 mjj(idim) = diag_z(col_indices(icol), idim)
1694 IF (row_indices(irow) /= col_indices(icol))
THEN
1695 CALL get_angle(mii, mjj, mij, weights, theta)
1696 theta = crazy_scale*theta
1697 IF (theta > limit_crazy_angle) theta = limit_crazy_angle
1698 IF (theta < -limit_crazy_angle) theta = -limit_crazy_angle
1699 IF (crazy_use_diag)
THEN
1700 cmat_a%local_data(irow, icol) = -cmplx(0.0_dp, theta,
dp)
1702 mat_theta%local_data(irow, icol) = -theta
1705 IF (crazy_use_diag)
THEN
1706 cmat_a%local_data(irow, icol) = czero
1708 mat_theta%local_data(irow, icol) = 0.0_dp
1716 IF (crazy_use_diag)
THEN
1718 maxeval = maxval(abs(evals))
1719 evals_exp(:) = exp((0.0_dp, -1.0_dp)*evals(:))
1722 CALL parallel_gemm(
'N',
'C', nrow_global, nrow_global, nrow_global, cone, &
1723 cmat_t1, cmat_r, czero, cmat_a)
1724 mat_u%local_data = real(cmat_a%local_data, kind=
dp)
1728 eps_exp = 1.0_dp*epsilon(eps_exp)
1737 CALL parallel_gemm(
'N',
'N', nrow_global, nrow_global, nrow_global, 1.0_dp, zij(1, idim), mat_u, 0.0_dp, mat_t)
1738 CALL parallel_gemm(
'T',
'N', nrow_global, nrow_global, nrow_global, 1.0_dp, mat_u, mat_t, 0.0_dp, zij(1, idim))
1739 CALL parallel_gemm(
'N',
'N', nrow_global, nrow_global, nrow_global, 1.0_dp, zij(2, idim), mat_u, 0.0_dp, mat_t)
1740 CALL parallel_gemm(
'T',
'N', nrow_global, nrow_global, nrow_global, 1.0_dp, mat_u, mat_t, 0.0_dp, zij(2, idim))
1743 CALL parallel_gemm(
'N',
'N', nrow_global, nrow_global, nrow_global, 1.0_dp, mat_r, mat_u, 0.0_dp, mat_t)
1746 CALL check_tolerance_new(weights, zij, tolerance,
value)
1748 IF (unit_nr > 0)
THEN
1749 WRITE (unit_nr,
'(T2,A7,I6,1X,G20.15,E12.4,E12.4,E12.4)') &
1750 "CRAZY| ", iterations,
value, tolerance, maxeval, limit_crazy_angle
1753 IF (tolerance < eps_localization .OR. iterations >= max_iter)
EXIT
1756 IF (
PRESENT(converged)) converged = (tolerance < eps_localization)
1769 DEALLOCATE (evals_exp, evals, diag_z)
1770 DEALLOCATE (mii, mij, mjj)
1772 CALL timestop(handle)
1790 SUBROUTINE direct_mini(weights, zij, vectors, max_iter, eps_localization, iterations)
1791 REAL(kind=
dp),
INTENT(IN) :: weights(:)
1792 TYPE(
cp_fm_type),
INTENT(IN) :: zij(:, :), vectors
1793 INTEGER,
INTENT(IN) :: max_iter
1794 REAL(kind=
dp),
INTENT(IN) :: eps_localization
1795 INTEGER :: iterations
1797 CHARACTER(len=*),
PARAMETER :: routinen =
'direct_mini'
1798 COMPLEX(KIND=dp),
PARAMETER :: cone = (1.0_dp, 0.0_dp), &
1799 czero = (0.0_dp, 0.0_dp)
1800 REAL(kind=
dp),
PARAMETER :: gold_sec = 0.3819_dp
1802 COMPLEX(KIND=dp) :: lk, ll, tmp
1803 COMPLEX(KIND=dp),
DIMENSION(:),
POINTER :: evals_exp
1804 COMPLEX(KIND=dp),
DIMENSION(:, :),
POINTER :: diag_z
1805 INTEGER :: handle, i, icol, idim, irow, &
1806 line_search_count, line_searches, lsl, &
1807 lsm, lsr, n, ncol_local, ndim, &
1808 nrow_local, output_unit
1809 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1810 LOGICAL :: new_direction
1811 REAL(kind=
dp) :: a, b, beta_pr, c, denom, ds, ds_min, fa, &
1812 fb, fc, nom, normg, normg_cross, &
1813 normg_old, npos, omega, tol, val, x0, &
1815 REAL(kind=
dp),
DIMENSION(150) :: energy, grad, pos
1816 REAL(kind=
dp),
DIMENSION(:),
POINTER :: evals, fval, fvald
1817 TYPE(
cp_cfm_type) :: cmat_a, cmat_b, cmat_m, cmat_r, cmat_t1, &
1819 TYPE(
cp_cfm_type),
ALLOCATABLE,
DIMENSION(:) :: c_zij
1820 TYPE(
cp_fm_type) :: matrix_a, matrix_g, matrix_g_old, &
1821 matrix_g_search, matrix_h, matrix_r, &
1824 NULLIFY (evals, evals_exp, diag_z, fval, fvald)
1826 CALL timeset(routinen, handle)
1829 n = zij(1, 1)%matrix_struct%nrow_global
1830 ndim = (
SIZE(zij, 2))
1832 IF (output_unit > 0)
THEN
1833 WRITE (output_unit,
'(T4,A )')
"Localization by direct minimization of the functional; "
1834 WRITE (output_unit,
'(T5,2A13,A20,A20,A10 )')
" Line search ",
" Iteration ",
" Functional ",
" Tolerance ",
" ds Min "
1837 ALLOCATE (evals(n), evals_exp(n), diag_z(n, ndim), fval(n), fvald(n))
1838 ALLOCATE (c_zij(ndim))
1843 c_zij(idim)%local_data = cmplx(zij(1, idim)%local_data, &
1844 zij(2, idim)%local_data,
dp)
1851 CALL cp_fm_create(matrix_g_search, zij(1, 1)%matrix_struct)
1852 CALL cp_fm_create(matrix_g_old, zij(1, 1)%matrix_struct)
1867 CALL cp_cfm_get_info(cmat_b, nrow_local=nrow_local, ncol_local=ncol_local, &
1868 row_indices=row_indices, col_indices=col_indices)
1872 normg_old = 1.0e30_dp
1874 new_direction = .true.
1877 line_search_count = 0
1879 iterations = iterations + 1
1881 cmat_a%local_data = cmplx(0.0_dp, matrix_a%local_data,
dp)
1883 evals_exp(:) = exp((0.0_dp, -1.0_dp)*evals(:))
1886 CALL parallel_gemm(
'N',
'C', n, n, n, cone, cmat_t1, cmat_r, czero, cmat_u)
1887 cmat_u%local_data = real(cmat_u%local_data, kind=
dp)
1889 IF (new_direction .AND. mod(line_searches, 20) == 5)
THEN
1891 CALL parallel_gemm(
'N',
'N', n, n, n, cone, c_zij(idim), cmat_u, czero, cmat_t1)
1892 CALL parallel_gemm(
'C',
'N', n, n, n, cone, cmat_u, cmat_t1, czero, c_zij(idim))
1895 matrix_h%local_data = real(cmat_u%local_data, kind=
dp)
1896 CALL parallel_gemm(
'N',
'N', n, n, n, 1.0_dp, matrix_r, matrix_h, 0.0_dp, matrix_t)
1904 evals_exp(:) = exp((0.0_dp, -1.0_dp)*evals(:))
1907 normg_old = 1.0e30_dp
1914 CALL parallel_gemm(
'N',
'N', n, n, n, cone, c_zij(idim), cmat_u, czero, cmat_t1)
1915 CALL parallel_gemm(
'C',
'N', n, n, n, cone, cmat_u, cmat_t1, czero, cmat_t2)
1920 fval(i) = -weights(idim)*log(abs(diag_z(i, idim))**2)
1921 fvald(i) = -weights(idim)/(abs(diag_z(i, idim))**2)
1923 fval(i) = weights(idim) - weights(idim)*abs(diag_z(i, idim))**2
1924 fvald(i) = -weights(idim)
1926 omega = omega + fval(i)
1928 DO icol = 1, ncol_local
1929 DO irow = 1, nrow_local
1930 tmp = cmat_t1%local_data(irow, icol)*conjg(diag_z(col_indices(icol), idim))
1931 cmat_m%local_data(irow, icol) = cmat_m%local_data(irow, icol) &
1932 + 4.0_dp*fvald(col_indices(icol))*real(tmp, kind=
dp)
1939 CALL gradsq_at_0(diag_z, weights, matrix_h, ndim)
1945 DO icol = 1, ncol_local
1946 DO irow = 1, nrow_local
1947 ll = (0.0_dp, -1.0_dp)*evals(row_indices(irow))
1948 lk = (0.0_dp, -1.0_dp)*evals(col_indices(icol))
1949 IF (abs(ll - lk) < 0.5_dp)
THEN
1951 cmat_b%local_data(irow, icol) = 0.0_dp
1953 cmat_b%local_data(irow, icol) = cmat_b%local_data(irow, icol) + tmp
1954 tmp = tmp*(ll - lk)/(i + 1)
1956 cmat_b%local_data(irow, icol) = cmat_b%local_data(irow, icol)*exp(lk)
1958 cmat_b%local_data(irow, icol) = (exp(lk) - exp(ll))/(lk - ll)
1964 CALL parallel_gemm(
'C',
'N', n, n, n, cone, cmat_m, cmat_r, czero, cmat_t1)
1965 CALL parallel_gemm(
'C',
'N', n, n, n, cone, cmat_r, cmat_t1, czero, cmat_t2)
1967 CALL parallel_gemm(
'N',
'C', n, n, n, cone, cmat_t1, cmat_r, czero, cmat_t2)
1968 CALL parallel_gemm(
'N',
'N', n, n, n, cone, cmat_r, cmat_t2, czero, cmat_t1)
1969 matrix_g%local_data = real(cmat_t1%local_data, kind=
dp)
1975 IF (new_direction)
THEN
1977 line_searches = line_searches + 1
1978 IF (output_unit > 0)
THEN
1979 WRITE (output_unit,
'(T5,I10,T18,I10,T31,2F20.6,F10.3)') line_searches, iterations, omega, tol, ds_min
1982 IF (tol < eps_localization .OR. iterations > max_iter)
EXIT
1985 CALL cp_fm_trace(matrix_g, matrix_g_old, normg_cross)
1986 normg_cross = normg_cross*0.5_dp
1988 DO icol = 1, ncol_local
1989 DO irow = 1, nrow_local
1990 matrix_g_old%local_data(irow, icol) = matrix_g%local_data(irow, icol)/matrix_h%local_data(irow, icol)
1994 normg = normg*0.5_dp
1995 beta_pr = (normg - normg_cross)/normg_old
1997 beta_pr = max(beta_pr, 0.0_dp)
1999 CALL cp_fm_trace(matrix_g_search, matrix_g_old, normg_cross)
2000 IF (normg_cross >= 0)
THEN
2001 IF (matrix_a%matrix_struct%para_env%is_source())
THEN
2011 line_search_count = 0
2013 line_search_count = line_search_count + 1
2014 energy(line_search_count) = omega
2019 SELECT CASE (line_search_count)
2023 CALL cp_fm_trace(matrix_g, matrix_g_search, grad(1))
2024 grad(1) = grad(1)/2.0_dp
2025 new_direction = .false.
2027 new_direction = .true.
2032 a = (energy(2) - b*x1 - c)/(x1**2)
2033 IF (a <= 0.0_dp) a = 1.0e-15_dp
2034 npos = -b/(2.0_dp*a)
2035 val = a*npos**2 + b*npos + c
2036 IF (val < energy(1) .AND. val <= energy(2))
THEN
2039 pos(3) = min(npos, maxval(pos(1:2))*4.0_dp)
2041 pos(3) = maxval(pos(1:2))*2.0_dp
2045 SELECT CASE (line_search_count)
2047 new_direction = .false.
2049 pos(2) = ds_min*0.8_dp
2051 new_direction = .false.
2052 IF (energy(2) > energy(1))
THEN
2053 pos(3) = ds_min*0.7_dp
2055 pos(3) = ds_min*1.4_dp
2058 new_direction = .true.
2065 nom = (xb - xa)**2*(fb - fc) - (xb -
xc)**2*(fb - fa)
2066 denom = (xb - xa)*(fb - fc) - (xb -
xc)*(fb - fa)
2067 IF (abs(denom) <= 1.0e-18_dp*max(abs(fb - fc), abs(fb - fa)))
THEN
2070 npos = xb - 0.5_dp*nom/denom
2072 val = (npos - xa)*(npos - xb)*fc/((
xc - xa)*(
xc - xb)) + &
2073 (npos - xb)*(npos -
xc)*fa/((xa - xb)*(xa -
xc)) + &
2074 (npos -
xc)*(npos - xa)*fb/((xb -
xc)*(xb - xa))
2075 IF (val < fa .AND. val <= fb .AND. val <= fc)
THEN
2077 pos(4) = max(maxval(pos(1:3))*0.01_dp, &
2078 min(npos, maxval(pos(1:3))*4.0_dp))
2080 pos(4) = maxval(pos(1:3))*2.0_dp
2084 new_direction = .false.
2085 IF (line_search_count == 1)
THEN
2090 pos(2) = ds_min/gold_sec
2092 IF (line_search_count == 150) cpabort(
"Too many")
2094 IF (energy(line_search_count - 1) < energy(line_search_count))
THEN
2095 lsr = line_search_count
2096 pos(line_search_count + 1) = pos(lsm) + (pos(lsr) - pos(lsm))*gold_sec
2099 lsm = line_search_count
2100 pos(line_search_count + 1) = pos(line_search_count)/gold_sec
2103 IF (pos(line_search_count) < pos(lsm))
THEN
2104 IF (energy(line_search_count) < energy(lsm))
THEN
2106 lsm = line_search_count
2108 lsl = line_search_count
2111 IF (energy(line_search_count) < energy(lsm))
THEN
2113 lsm = line_search_count
2115 lsr = line_search_count
2118 IF (pos(lsr) - pos(lsm) > pos(lsm) - pos(lsl))
THEN
2119 pos(line_search_count + 1) = pos(lsm) + gold_sec*(pos(lsr) - pos(lsm))
2121 pos(line_search_count + 1) = pos(lsl) + gold_sec*(pos(lsm) - pos(lsl))
2123 IF ((pos(lsr) - pos(lsl)) < 1.0e-3_dp*pos(lsr))
THEN
2124 new_direction = .true.
2130 ds_min = pos(line_search_count + 1)
2131 ds = pos(line_search_count + 1) - pos(line_search_count)
2136 matrix_h%local_data = real(cmat_u%local_data, kind=
dp)
2137 CALL parallel_gemm(
'N',
'N', n, n, n, 1.0_dp, matrix_r, matrix_h, 0.0_dp, matrix_t)
2156 DEALLOCATE (evals, evals_exp, fval, fvald)
2158 DO idim = 1,
SIZE(c_zij)
2159 zij(1, idim)%local_data = real(c_zij(idim)%local_data,
dp)
2160 zij(2, idim)%local_data = aimag(c_zij(idim)%local_data)
2166 CALL timestop(handle)
2187 SUBROUTINE jacobi_rot_para(weights, zij, vectors, para_env, max_iter, eps_localization, &
2188 sweeps, out_each, target_time, start_time, restricted)
2190 REAL(kind=
dp),
INTENT(IN) :: weights(:)
2191 TYPE(
cp_fm_type),
INTENT(IN) :: zij(:, :), vectors
2193 INTEGER,
INTENT(IN) :: max_iter
2194 REAL(kind=
dp),
INTENT(IN) :: eps_localization
2196 INTEGER,
INTENT(IN) :: out_each
2197 REAL(
dp) :: target_time, start_time
2198 INTEGER :: restricted
2200 CHARACTER(len=*),
PARAMETER :: routinen =
'jacobi_rot_para'
2202 INTEGER :: dim2, handle, i, idim, ii, ilow1, ip, j, &
2203 nblock, nblock_max, ns_me, nstate, &
2205 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: ns_bound
2206 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: rotmat, z_ij_loc_im, z_ij_loc_re
2207 REAL(kind=
dp) :: xstate
2209 TYPE(set_c_2d_type),
DIMENSION(:),
POINTER :: cz_ij_loc
2211 CALL timeset(routinen, handle)
2224 IF (restricted > 0)
THEN
2225 IF (output_unit > 0)
THEN
2226 WRITE (output_unit,
'(T4,A,I2,A )')
"JACOBI: for the ROKS method, the last ", restricted,
" orbitals DO NOT ROTATE"
2228 nstate = nstate - restricted
2232 xstate = real(nstate,
dp)/real(para_env%num_pe,
dp)
2233 ALLOCATE (ns_bound(0:para_env%num_pe - 1, 2))
2234 DO ip = 1, para_env%num_pe
2235 ns_bound(ip - 1, 1) = min(nstate, nint(xstate*(ip - 1))) + 1
2236 ns_bound(ip - 1, 2) = min(nstate, nint(xstate*ip))
2239 DO ip = 0, para_env%num_pe - 1
2240 nblock = ns_bound(ip, 2) - ns_bound(ip, 1) + 1
2241 nblock_max = max(nblock_max, nblock)
2245 ALLOCATE (z_ij_loc_re(nstate, nblock_max))
2246 ALLOCATE (z_ij_loc_im(nstate, nblock_max))
2247 ALLOCATE (cz_ij_loc(dim2))
2249 DO ip = 0, para_env%num_pe - 1
2250 nblock = ns_bound(ip, 2) - ns_bound(ip, 1) + 1
2253 IF (para_env%mepos == ip)
THEN
2254 ALLOCATE (cz_ij_loc(idim)%c_array(nstate, nblock))
2257 cz_ij_loc(idim)%c_array(j, i) = cmplx(z_ij_loc_re(j, i), z_ij_loc_im(j, i),
dp)
2263 DEALLOCATE (z_ij_loc_re)
2264 DEALLOCATE (z_ij_loc_im)
2266 ALLOCATE (rotmat(nstate, 2*nblock_max))
2268 CALL jacobi_rot_para_core(weights, para_env, max_iter, sweeps, out_each, dim2, nstate, nblock_max, ns_bound, &
2269 cz_ij_loc, rotmat, output_unit, eps_localization=eps_localization, &
2270 target_time=target_time, start_time=start_time)
2272 ilow1 = ns_bound(para_env%mepos, 1)
2273 ns_me = ns_bound(para_env%mepos, 2) - ns_bound(para_env%mepos, 1) + 1
2274 ALLOCATE (z_ij_loc_re(nstate, nblock_max))
2275 ALLOCATE (z_ij_loc_im(nstate, nblock_max))
2277 DO ip = 0, para_env%num_pe - 1
2278 z_ij_loc_re = 0.0_dp
2279 z_ij_loc_im = 0.0_dp
2280 nblock = ns_bound(ip, 2) - ns_bound(ip, 1) + 1
2281 IF (ip == para_env%mepos)
THEN
2286 z_ij_loc_re(j, i) = real(cz_ij_loc(idim)%c_array(j, i),
dp)
2287 z_ij_loc_im(j, i) = aimag(cz_ij_loc(idim)%c_array(j, i))
2291 CALL para_env%bcast(z_ij_loc_re, ip)
2292 CALL para_env%bcast(z_ij_loc_im, ip)
2298 DO ip = 0, para_env%num_pe - 1
2299 z_ij_loc_re = 0.0_dp
2300 nblock = ns_bound(ip, 2) - ns_bound(ip, 1) + 1
2301 IF (ip == para_env%mepos)
THEN
2306 z_ij_loc_re(j, i) = rotmat(j, i)
2310 CALL para_env%bcast(z_ij_loc_re, ip)
2314 DEALLOCATE (z_ij_loc_re)
2315 DEALLOCATE (z_ij_loc_im)
2317 DEALLOCATE (cz_ij_loc(idim)%c_array)
2319 DEALLOCATE (cz_ij_loc)
2321 CALL para_env%sync()
2326 DEALLOCATE (ns_bound)
2328 CALL timestop(handle)
2330 END SUBROUTINE jacobi_rot_para
2342 SUBROUTINE jacobi_rot_para_1(weights, czij, para_env, max_iter, rmat, tol_out)
2344 REAL(kind=
dp),
INTENT(IN) :: weights(:)
2347 INTEGER,
INTENT(IN) :: max_iter
2349 REAL(
dp),
INTENT(OUT),
OPTIONAL :: tol_out
2351 CHARACTER(len=*),
PARAMETER :: routinen =
'jacobi_rot_para_1'
2353 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: czij_array
2354 INTEGER :: dim2, handle, i, idim, ii, ilow1, ip, j, &
2355 nblock, nblock_max, ns_me, nstate, &
2357 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: ns_bound
2358 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: rotmat, z_ij_loc_re
2359 REAL(kind=
dp) :: xstate
2360 TYPE(set_c_2d_type),
DIMENSION(:),
POINTER :: cz_ij_loc
2362 CALL timeset(routinen, handle)
2371 xstate = real(nstate,
dp)/real(para_env%num_pe,
dp)
2372 ALLOCATE (ns_bound(0:para_env%num_pe - 1, 2))
2373 DO ip = 1, para_env%num_pe
2374 ns_bound(ip - 1, 1) = min(nstate, nint(xstate*(ip - 1))) + 1
2375 ns_bound(ip - 1, 2) = min(nstate, nint(xstate*ip))
2378 DO ip = 0, para_env%num_pe - 1
2379 nblock = ns_bound(ip, 2) - ns_bound(ip, 1) + 1
2380 nblock_max = max(nblock_max, nblock)
2384 ALLOCATE (czij_array(nstate, nblock_max))
2385 ALLOCATE (cz_ij_loc(dim2))
2387 DO ip = 0, para_env%num_pe - 1
2388 nblock = ns_bound(ip, 2) - ns_bound(ip, 1) + 1
2391 IF (para_env%mepos == ip)
THEN
2393 ALLOCATE (cz_ij_loc(idim)%c_array(nstate, ns_me))
2396 cz_ij_loc(idim)%c_array(j, i) = czij_array(j, i)
2402 DEALLOCATE (czij_array)
2404 ALLOCATE (rotmat(nstate, 2*nblock_max))
2406 CALL jacobi_rot_para_core(weights, para_env, max_iter, sweeps, 1, dim2, nstate, nblock_max, ns_bound, &
2407 cz_ij_loc, rotmat, 0, tol_out=tol_out)
2409 ilow1 = ns_bound(para_env%mepos, 1)
2410 ns_me = ns_bound(para_env%mepos, 2) - ns_bound(para_env%mepos, 1) + 1
2411 ALLOCATE (z_ij_loc_re(nstate, nblock_max))
2413 DO ip = 0, para_env%num_pe - 1
2414 z_ij_loc_re = 0.0_dp
2415 nblock = ns_bound(ip, 2) - ns_bound(ip, 1) + 1
2416 IF (ip == para_env%mepos)
THEN
2421 z_ij_loc_re(j, i) = rotmat(j, i)
2425 CALL para_env%bcast(z_ij_loc_re, ip)
2429 DEALLOCATE (z_ij_loc_re)
2431 DEALLOCATE (cz_ij_loc(idim)%c_array)
2433 DEALLOCATE (cz_ij_loc)
2435 CALL para_env%sync()
2438 DEALLOCATE (ns_bound)
2440 CALL timestop(handle)
2442 END SUBROUTINE jacobi_rot_para_1
2466 SUBROUTINE jacobi_rot_para_core(weights, para_env, max_iter, sweeps, out_each, dim2, nstate, nblock_max, &
2467 ns_bound, cz_ij_loc, rotmat, output_unit, tol_out, eps_localization, target_time, start_time)
2469 REAL(kind=
dp),
INTENT(IN) :: weights(:)
2471 INTEGER,
INTENT(IN) :: max_iter
2472 INTEGER,
INTENT(OUT) :: sweeps
2473 INTEGER,
INTENT(IN) :: out_each, dim2, nstate, nblock_max
2474 INTEGER,
DIMENSION(0:, :),
INTENT(IN) :: ns_bound
2475 TYPE(set_c_2d_type),
DIMENSION(:),
POINTER :: cz_ij_loc
2476 REAL(
dp),
DIMENSION(:, :),
INTENT(OUT) :: rotmat
2477 INTEGER,
INTENT(IN) :: output_unit
2478 REAL(
dp),
INTENT(OUT),
OPTIONAL :: tol_out
2479 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_localization
2480 REAL(
dp),
OPTIONAL :: target_time, start_time
2482 COMPLEX(KIND=dp) :: zi, zj
2483 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: c_array_me, c_array_partner
2484 COMPLEX(KIND=dp),
POINTER :: mii(:), mij(:), mjj(:)
2485 INTEGER :: i, idim, ii, ik, il1, il2, il_recv, il_recv_partner, ilow1, ilow2, ip, ip_has_i, &
2486 ip_partner, ip_recv_from, ip_recv_partner, ipair, iperm, istate, iu1, iu2, iup1, iup2, j, &
2487 jj, jstate, k, kk, lsweep, n1, n2, npair, nperm, ns_me, ns_partner, ns_recv_from, &
2489 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: rcount, rdispl
2490 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: list_pair
2491 LOGICAL :: should_stop
2492 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: gmat, rmat_loc, rmat_recv, rmat_send
2493 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: rmat_recv_all
2494 REAL(kind=
dp) :: ct, func, gmax, grad, ri, rj, st, t1, &
2495 t2, theta, tolerance, zc, zr
2496 TYPE(set_c_1d_type),
DIMENSION(:),
POINTER :: zdiag_all, zdiag_me
2497 TYPE(set_c_2d_type),
DIMENSION(:),
POINTER :: xyz_mix, xyz_mix_ns
2499 NULLIFY (zdiag_all, zdiag_me)
2500 NULLIFY (xyz_mix, xyz_mix_ns)
2501 NULLIFY (mii, mij, mjj)
2503 ALLOCATE (mii(dim2), mij(dim2), mjj(dim2))
2505 ALLOCATE (rcount(para_env%num_pe))
2506 ALLOCATE (rdispl(para_env%num_pe))
2508 tolerance = 1.0e10_dp
2512 npair = (para_env%num_pe + 1)/2
2513 nperm = para_env%num_pe - mod(para_env%num_pe + 1, 2)
2514 ALLOCATE (list_pair(2, npair))
2518 DO i = ns_bound(para_env%mepos, 1), ns_bound(para_env%mepos, 2)
2519 ii = i - ns_bound(para_env%mepos, 1) + 1
2520 rotmat(i, ii) = 1.0_dp
2523 ALLOCATE (xyz_mix(dim2))
2524 ALLOCATE (xyz_mix_ns(dim2))
2525 ALLOCATE (zdiag_me(dim2))
2526 ALLOCATE (zdiag_all(dim2))
2528 ns_me = ns_bound(para_env%mepos, 2) - ns_bound(para_env%mepos, 1) + 1
2529 IF (ns_me /= 0)
THEN
2530 ALLOCATE (c_array_me(nstate, ns_me, dim2))
2532 ALLOCATE (xyz_mix_ns(idim)%c_array(nstate, ns_me))
2534 ALLOCATE (gmat(nstate, ns_me))
2538 ALLOCATE (zdiag_me(idim)%c_array(nblock_max))
2539 zdiag_me(idim)%c_array =
z_zero
2540 ALLOCATE (zdiag_all(idim)%c_array(para_env%num_pe*nblock_max))
2541 zdiag_all(idim)%c_array =
z_zero
2543 ALLOCATE (rmat_recv(nblock_max*2, nblock_max))
2544 ALLOCATE (rmat_send(nblock_max*2, nblock_max))
2547 ALLOCATE (rmat_recv_all(nblock_max*2, nblock_max, 0:para_env%num_pe - 1))
2549 IF (output_unit > 0)
THEN
2550 WRITE (output_unit,
'(T4,A )')
" Localization by iterative distributed Jacobi rotation"
2551 WRITE (output_unit,
'(T20,A12,T32, A22,T60, A12,A8 )')
"Iteration",
"Functional",
"Tolerance",
" Time "
2554 DO lsweep = 1, max_iter + 1
2556 IF (sweeps == max_iter + 1)
THEN
2557 IF (output_unit > 0)
THEN
2558 WRITE (output_unit, *)
' LOCALIZATION! loop did not converge within the maximum number of iterations.'
2559 WRITE (output_unit, *)
' Present Max. gradient = ', tolerance
2568 CALL eberlein(iperm, para_env, list_pair)
2572 IF (list_pair(1, ipair) == para_env%mepos)
THEN
2573 ip_partner = list_pair(2, ipair)
2575 ELSE IF (list_pair(2, ipair) == para_env%mepos)
THEN
2576 ip_partner = list_pair(1, ipair)
2580 IF (ip_partner >= 0)
THEN
2581 ns_partner = ns_bound(ip_partner, 2) - ns_bound(ip_partner, 1) + 1
2587 IF (ns_partner*ns_me /= 0)
THEN
2589 ALLOCATE (rmat_loc(ns_me + ns_partner, ns_me + ns_partner))
2591 DO i = 1, ns_me + ns_partner
2592 rmat_loc(i, i) = 1.0_dp
2595 ALLOCATE (c_array_partner(nstate, ns_partner, dim2))
2598 ALLOCATE (xyz_mix(idim)%c_array(ns_me + ns_partner, ns_me + ns_partner))
2600 c_array_me(1:nstate, i, idim) = cz_ij_loc(idim)%c_array(1:nstate, i)
2604 CALL para_env%sendrecv(msgin=c_array_me, dest=ip_partner, &
2605 msgout=c_array_partner, source=ip_partner)
2609 ilow1 = ns_bound(para_env%mepos, 1)
2610 iup1 = ns_bound(para_env%mepos, 1) + n1 - 1
2611 ilow2 = ns_bound(ip_partner, 1)
2612 iup2 = ns_bound(ip_partner, 1) + n2 - 1
2613 IF (ns_bound(para_env%mepos, 1) < ns_bound(ip_partner, 1))
THEN
2629 xyz_mix(idim)%c_array(il1:iu1, il1 + i - 1) = c_array_me(ilow1:iup1, i, idim)
2630 xyz_mix(idim)%c_array(il2:iu2, il1 + i - 1) = c_array_me(ilow2:iup2, i, idim)
2633 xyz_mix(idim)%c_array(il2:iu2, il2 + i - 1) = c_array_partner(ilow2:iup2, i, idim)
2634 xyz_mix(idim)%c_array(il1:iu1, il2 + i - 1) = c_array_partner(ilow1:iup1, i, idim)
2638 DO istate = 1, n1 + n2
2639 DO jstate = istate + 1, n1 + n2
2641 mii(idim) = xyz_mix(idim)%c_array(istate, istate)
2642 mij(idim) = xyz_mix(idim)%c_array(istate, jstate)
2643 mjj(idim) = xyz_mix(idim)%c_array(jstate, jstate)
2645 CALL get_angle(mii, mjj, mij, weights, theta)
2650 zi = ct*xyz_mix(idim)%c_array(i, istate) + st*xyz_mix(idim)%c_array(i, jstate)
2651 zj = -st*xyz_mix(idim)%c_array(i, istate) + ct*xyz_mix(idim)%c_array(i, jstate)
2652 xyz_mix(idim)%c_array(i, istate) = zi
2653 xyz_mix(idim)%c_array(i, jstate) = zj
2656 zi = ct*xyz_mix(idim)%c_array(istate, i) + st*xyz_mix(idim)%c_array(jstate, i)
2657 zj = -st*xyz_mix(idim)%c_array(istate, i) + ct*xyz_mix(idim)%c_array(jstate, i)
2658 xyz_mix(idim)%c_array(istate, i) = zi
2659 xyz_mix(idim)%c_array(jstate, i) = zj
2664 ri = ct*rmat_loc(i, istate) + st*rmat_loc(i, jstate)
2665 rj = ct*rmat_loc(i, jstate) - st*rmat_loc(i, istate)
2666 rmat_loc(i, istate) = ri
2667 rmat_loc(i, jstate) = rj
2673 CALL para_env%sendrecv(rotmat(1:nstate, 1:ns_me), ip_partner, &
2674 rotmat(1:nstate, k:k + n2 - 1), ip_partner)
2676 IF (ilow1 < ilow2)
THEN
2679 CALL dgemm(
"N",
"N", nstate, n1, n2, 1.0_dp, rotmat(1:, k:), nstate, rmat_loc(1 + n1:, 1:n1), &
2680 n2, 0.0_dp, gmat(:, :), nstate)
2681 CALL dgemm(
"N",
"N", nstate, n1, n1, 1.0_dp, rotmat(1:, 1:), nstate, rmat_loc(1:, 1:), &
2682 n1 + n2, 1.0_dp, gmat(:, :), nstate)
2684 CALL dgemm(
"N",
"N", nstate, n1, n2, 1.0_dp, rotmat(1:, k:), nstate, &
2685 rmat_loc(1:, n2 + 1:), n1 + n2, 0.0_dp, gmat(:, :), nstate)
2688 CALL dgemm(
"N",
"N", nstate, n1, n1, 1.0_dp, rotmat(1:, 1:), nstate, rmat_loc(n2 + 1:, n2 + 1:), &
2689 n1, 1.0_dp, gmat(:, :), nstate)
2692 CALL dcopy(nstate*n1, gmat(1, 1), 1, rotmat(1, 1), 1)
2696 xyz_mix_ns(idim)%c_array(1:nstate, i) =
z_zero
2700 DO jstate = 1, nstate
2702 xyz_mix_ns(idim)%c_array(jstate, istate) = &
2703 xyz_mix_ns(idim)%c_array(jstate, istate) + &
2704 c_array_partner(jstate, i, idim)*rmat_loc(il2 + i - 1, il1 + istate - 1)
2709 DO jstate = 1, nstate
2711 xyz_mix_ns(idim)%c_array(jstate, istate) = xyz_mix_ns(idim)%c_array(jstate, istate) + &
2712 c_array_me(jstate, i, idim)*rmat_loc(il1 + i - 1, il1 + istate - 1)
2718 DEALLOCATE (c_array_partner)
2723 xyz_mix_ns(idim)%c_array(1:nstate, i) = cz_ij_loc(idim)%c_array(1:nstate, i)
2730 cz_ij_loc(idim)%c_array(1:nstate, i) =
z_zero
2734 IF (ns_partner*ns_me /= 0)
THEN
2736 DO i = 1, ns_me + ns_partner
2737 DO j = i + 1, ns_me + ns_partner
2739 rmat_loc(i, j) = rmat_loc(j, i)
2746 rmat_send(1:n1, i) = rmat_loc(il1:iu1, il1 + i - 1)
2750 rmat_send(ik + 1:ik + n1, i) = rmat_loc(il1:iu1, il2 + i - 1)
2757 CALL para_env%allgather(rmat_send, rmat_recv_all)
2760 DO ip = 0, para_env%num_pe - 1
2762 ip_recv_from = mod(para_env%mepos - ip + para_env%num_pe, para_env%num_pe)
2763 rmat_recv(:, :) = rmat_recv_all(:, :, ip_recv_from)
2765 ns_recv_from = ns_bound(ip_recv_from, 2) - ns_bound(ip_recv_from, 1) + 1
2767 IF (ns_me /= 0)
THEN
2768 IF (ns_recv_from /= 0)
THEN
2770 ip_recv_partner = -1
2773 IF (list_pair(1, ipair) == ip_recv_from)
THEN
2774 ip_recv_partner = list_pair(2, ipair)
2776 ELSE IF (list_pair(2, ipair) == ip_recv_from)
THEN
2777 ip_recv_partner = list_pair(1, ipair)
2782 IF (ip_recv_partner >= 0)
THEN
2783 ns_recv_partner = ns_bound(ip_recv_partner, 2) - ns_bound(ip_recv_partner, 1) + 1
2785 IF (ns_recv_partner > 0)
THEN
2786 il1 = ns_bound(para_env%mepos, 1)
2787 il_recv = ns_bound(ip_recv_from, 1)
2788 il_recv_partner = ns_bound(ip_recv_partner, 1)
2792 DO i = 1, ns_recv_from
2793 ii = il_recv + i - 1
2796 DO k = 1, ns_recv_from
2797 kk = il_recv + k - 1
2798 cz_ij_loc(idim)%c_array(ii, jj) = cz_ij_loc(idim)%c_array(ii, jj) + &
2799 rmat_recv(i, k)*xyz_mix_ns(idim)%c_array(kk, j)
2803 DO i = 1, ns_recv_from
2804 ii = il_recv + i - 1
2807 DO k = 1, ns_recv_partner
2808 kk = il_recv_partner + k - 1
2809 cz_ij_loc(idim)%c_array(ii, jj) = cz_ij_loc(idim)%c_array(ii, jj) + &
2810 rmat_recv(ik + i, k)*xyz_mix_ns(idim)%c_array(kk, j)
2816 il1 = ns_bound(para_env%mepos, 1)
2817 il_recv = ns_bound(ip_recv_from, 1)
2821 DO i = 1, ns_recv_from
2822 ii = il_recv + i - 1
2823 cz_ij_loc(idim)%c_array(ii, jj) = xyz_mix_ns(idim)%c_array(ii, j)
2832 IF (ns_partner*ns_me /= 0)
THEN
2833 DEALLOCATE (rmat_loc)
2835 DEALLOCATE (xyz_mix(idim)%c_array)
2843 DO i = ns_bound(para_env%mepos, 1), ns_bound(para_env%mepos, 2)
2844 ii = i - ns_bound(para_env%mepos, 1) + 1
2845 zdiag_me(idim)%c_array(ii) = cz_ij_loc(idim)%c_array(i, ii)
2846 zdiag_me(idim)%c_array(ii) = cz_ij_loc(idim)%c_array(i, ii)
2848 rcount(:) =
SIZE(zdiag_me(idim)%c_array)
2850 DO ip = 2, para_env%num_pe
2851 rdispl(ip) = rdispl(ip - 1) + rcount(ip - 1)
2854 CALL para_env%allgatherv(zdiag_me(idim)%c_array, zdiag_all(idim)%c_array, rcount, rdispl)
2858 DO j = ns_bound(para_env%mepos, 1), ns_bound(para_env%mepos, 2)
2859 k = j - ns_bound(para_env%mepos, 1) + 1
2862 DO ip = 0, para_env%num_pe - 1
2863 IF (i >= ns_bound(ip, 1) .AND. i <= ns_bound(ip, 2))
THEN
2868 ii = nblock_max*ip_has_i + i - ns_bound(ip_has_i, 1) + 1
2870 jj = nblock_max*para_env%mepos + j - ns_bound(para_env%mepos, 1) + 1
2873 zi = zdiag_all(idim)%c_array(ii)
2874 zj = zdiag_all(idim)%c_array(jj)
2875 grad = grad + weights(idim)*real(4.0_dp*conjg(cz_ij_loc(idim)%c_array(i, k))*(zj - zi),
dp)
2877 gmax = max(gmax, abs(grad))
2881 CALL para_env%max(gmax)
2883 IF (
PRESENT(tol_out)) tol_out = tolerance
2886 DO i = ns_bound(para_env%mepos, 1), ns_bound(para_env%mepos, 2)
2887 k = i - ns_bound(para_env%mepos, 1) + 1
2889 zr = real(cz_ij_loc(idim)%c_array(i, k),
dp)
2890 zc = aimag(cz_ij_loc(idim)%c_array(i, k))
2891 func = func + weights(idim)*(1.0_dp - (zr*zr + zc*zc))/
twopi/
twopi
2894 CALL para_env%sum(func)
2897 IF (output_unit > 0 .AND.
modulo(sweeps, out_each) == 0)
THEN
2898 WRITE (output_unit,
'(T20,I12,T35,F20.10,T60,E12.4,F8.3)') sweeps, func, tolerance, t2 - t1
2901 IF (
PRESENT(eps_localization))
THEN
2902 IF (tolerance < eps_localization)
EXIT
2904 IF (
PRESENT(target_time) .AND.
PRESENT(start_time))
THEN
2905 CALL external_control(should_stop,
"LOC", target_time=target_time, start_time=start_time)
2906 IF (should_stop)
EXIT
2912 DEALLOCATE (rmat_recv_all)
2914 DEALLOCATE (rmat_recv)
2915 DEALLOCATE (rmat_send)
2917 DEALLOCATE (c_array_me)
2920 DEALLOCATE (zdiag_me(idim)%c_array)
2921 DEALLOCATE (zdiag_all(idim)%c_array)
2923 DEALLOCATE (zdiag_me)
2924 DEALLOCATE (zdiag_all)
2925 DEALLOCATE (xyz_mix)
2927 IF (ns_me /= 0)
THEN
2928 DEALLOCATE (xyz_mix_ns(idim)%c_array)
2931 DEALLOCATE (xyz_mix_ns)
2932 IF (ns_me /= 0)
THEN
2938 DEALLOCATE (list_pair)
2940 END SUBROUTINE jacobi_rot_para_core
2948 SUBROUTINE eberlein(iperm, para_env, list_pair)
2949 INTEGER,
INTENT(IN) :: iperm
2951 INTEGER,
DIMENSION(:, :) :: list_pair
2953 INTEGER :: i, ii, jj, npair
2955 npair = (para_env%num_pe + 1)/2
2956 IF (iperm == 1)
THEN
2958 DO i = 0, para_env%num_pe - 1
2959 ii = ((i + 1) + 1)/2
2960 jj = mod((i + 1) + 1, 2) + 1
2961 list_pair(jj, ii) = i
2963 IF (mod(para_env%num_pe, 2) == 1) list_pair(2, npair) = -1
2964 ELSE IF (mod(iperm, 2) == 0)
THEN
2966 jj = list_pair(1, npair)
2968 list_pair(1, i) = list_pair(1, i - 1)
2970 list_pair(1, 2) = list_pair(2, 1)
2971 list_pair(2, 1) = jj
2974 jj = list_pair(2, 1)
2976 list_pair(2, i) = list_pair(2, i + 1)
2978 list_pair(2, npair) = jj
2981 END SUBROUTINE eberlein
2992 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: op_sm_set
2993 TYPE(
cp_fm_type),
DIMENSION(:, :),
INTENT(IN) :: zij_fm_set
2995 CHARACTER(len=*),
PARAMETER :: routinen =
'zij_matrix'
2997 INTEGER :: handle, i, j, nao, nmoloc
3000 CALL timeset(routinen, handle)
3003 CALL cp_fm_get_info(vectors, nrow_global=nao, ncol_global=nmoloc)
3008 DO i = 1,
SIZE(zij_fm_set, 2)
3009 DO j = 1,
SIZE(zij_fm_set, 1)
3012 CALL parallel_gemm(
"T",
"N", nmoloc, nmoloc, nao, 1.0_dp, vectors, opvec, 0.0_dp, &
3018 CALL timestop(handle)
3030 CHARACTER(len=*),
PARAMETER :: routinen =
'scdm_qrfact'
3032 INTEGER :: handle, ncolt, nrowt
3033 REAL(kind=
dp),
DIMENSION(:),
POINTER :: tau
3037 CALL timeset(routinen, handle)
3040 nrowt = vectors%matrix_struct%ncol_global
3041 ncolt = vectors%matrix_struct%nrow_global
3044 nrow_global=nrowt, ncol_global=ncolt)
3048 ALLOCATE (tau(nrowt))
3057 context=ctp%matrix_struct%context, nrow_global=ctp%matrix_struct%nrow_global, &
3058 ncol_global=ctp%matrix_struct%nrow_global)
3070 CALL parallel_gemm(
'N',
'N', ncolt, nrowt, nrowt, 1.0_dp, tmp, qf, 0.0_dp, vectors)
3078 CALL timestop(handle)
3100 REAL(kind=
dp),
INTENT(IN) :: weights(:)
3102 INTEGER,
INTENT(IN) :: max_iter
3103 REAL(kind=
dp),
INTENT(IN) :: eps_localization
3105 INTEGER,
INTENT(IN) :: out_each
3108 CHARACTER(len=*),
PARAMETER :: routinen =
'cardoso_souloumiac'
3110 COMPLEX(KIND=dp) :: s
3111 COMPLEX(KIND=dp),
ALLOCATABLE :: mii(:), mij(:), mji(:), mjj(:)
3112 INTEGER :: dim1, dim2, handle, idim, istate, jdim, &
3113 jstate, nstate, unit_nr
3114 REAL(kind=
dp) :: c, old_spread, spread, t1, t2, tolerance
3117 CALL timeset(routinen, handle)
3122 NULLIFY (c_rmat, c_zij)
3123 ALLOCATE (c_rmat, c_zij(dim1*dim2), mii(dim1*dim2), mij(dim1*dim2), mji(dim1*dim2), mjj(dim1*dim2))
3128 CALL cp_cfm_create(c_zij((idim - 1)*dim1 + jdim), zij(jdim, idim)%matrix_struct)
3129 CALL cp_cfm_to_cfm(zij(jdim, idim), c_zij((idim - 1)*dim1 + jdim))
3134 tolerance = 1.0e10_dp
3135 old_spread = 1.0e10_dp
3138 IF (c_rmat%matrix_struct%para_env%is_source())
THEN
3140 WRITE (unit_nr,
"(T4,A )")
" Localization by iterative Jacobi rotation using "// &
3141 "Cardoso-Souloumiac angles"
3146 DO WHILE (tolerance >= eps_localization .AND. sweeps < max_iter)
3149 DO jstate = 1, nstate
3150 DO istate = jstate + 1, nstate
3151 DO idim = 1, dim1*dim2
3157 CALL get_cardoso_angles(mii, mij, mji, mjj, c, s, vectors%matrix_struct)
3158 DO idim = 1, dim1*dim2
3165 CALL check_tolerance(c_zij, weights, spread)
3166 CALL check_tolerance(c_zij, weights, tolerance)
3167 tolerance = abs(spread - old_spread)
3171 IF (unit_nr > 0 .AND.
modulo(sweeps, out_each) == 0)
THEN
3172 WRITE (unit_nr,
"(T4,A,I7,A,E12.4,A,E12.4,A,F8.3)") &
3173 "Iteration:", sweeps,
"Functional", spread,
"Tolerance:", tolerance,
"Time:", t2 - t1
3181 CALL cp_cfm_to_cfm(c_zij((idim - 1)*dim1 + jdim), zij(jdim, idim))
3186 CALL rotate_orbitals_cfm(c_rmat, vectors)
3188 DEALLOCATE (c_zij, mii, mij, mji, mjj)
3192 CALL timestop(handle)
3211 INTEGER :: sweeps, max_iter
3215 CHARACTER(*),
PARAMETER :: routinen =
'cardoso_souloumiac_pipek'
3217 COMPLEX(dp) :: c_spread, s
3218 COMPLEX(dp),
POINTER :: qii(:), qij(:), qji(:), qjj(:)
3219 INTEGER :: handle, i, j, k, n_dim, n_states, &
3221 REAL(
dp) :: c, old_spread, spread, t1, t2, tol
3224 CALL timeset(routinen, handle)
3234 ALLOCATE (c_zij(n_dim), qii(n_dim), qij(n_dim), qji(n_dim), qjj(n_dim))
3238 c_zij(k) = zij(k, 1)
3244 c_spread = (0.0_dp, 0.0_dp)
3248 c_spread = c_spread + s*s
3251 spread = real(c_spread)
3256 WRITE (output_unit,
"(T4,A )")
" Localization by iterative Jacobi rotation using "// &
3257 "Cardoso-Souloumiac angles"
3258 WRITE (output_unit,
"(T4,A )")
" and Pipek-Mezey spread functional"
3260 IF (output_unit > 0 .AND.
modulo(sweeps, out_each) == 0)
THEN
3261 WRITE (output_unit,
"(T4,A,I7,A,E12.4,A,E12.4,A,F8.3)") &
3262 "Iteration:", sweeps,
" Functional", spread,
" Tolerance:", tol,
" Time:", 0.0_dp
3265 DO WHILE (tol >= eps .AND. sweeps < max_iter)
3270 DO j = i + 1, n_states
3277 CALL get_cardoso_angles(qii, qij, qji, qjj, c, s, vec%matrix_struct)
3286 c_spread = (0.0_dp, 0.0_dp)
3290 c_spread = c_spread + s*s
3293 spread = real(c_spread)
3295 tol = abs(spread - old_spread)
3298 IF (output_unit > 0 .AND.
modulo(sweeps, out_each) == 0)
THEN
3299 WRITE (output_unit,
"(T4,A,I7,A,E12.4,A,E12.4,A,F8.3)") &
3300 "Iteration:", sweeps,
" Functional", spread,
" Tolerance:", tol,
" Time:", t2 - t1
3304 CALL rotate_orbitals_cfm(rmat, vec)
3307 DEALLOCATE (c_zij, qii, qij, qji, qjj)
3311 CALL timestop(handle)
3328 SUBROUTINE get_cardoso_angles(mii, mij, mji, mjj, c, s, tmp_fm_struct)
3330 COMPLEX(KIND=dp),
DIMENSION(:) :: mii, mij, mji, mjj
3331 REAL(kind=
dp),
INTENT(out) :: c
3332 COMPLEX(KIND=dp),
INTENT(out) :: s
3335 INTEGER :: dim_m, i, i_max
3336 REAL(kind=
dp) :: r, x, y, z
3337 REAL(kind=
dp),
DIMENSION(3) :: evals
3345 template_fmstruct=tmp_fm_struct)
3347 template_fmstruct=tmp_fm_struct)
3348 ALLOCATE (hmat, c_gmat, gmat, evects)
3359 CALL cp_cfm_gemm(
"C",
"N", 3, 3, 1, (1.0_dp, 0.0_dp), hmat, hmat, (1.0_dp, 0.0_dp), c_gmat)
3365 i_max = maxloc(evals, 1)
3376 r = sqrt(x**2 + y**2 + z**2)
3377 c = sqrt((x + r)/(2*r))
3378 s = (y -
gaussi*z)/sqrt(2*r*(x + r))
3386 DEALLOCATE (hmat, c_gmat, gmat, evects)
3388 END SUBROUTINE get_cardoso_angles
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public schreder2024_2
Handles all functions related to the CELL.
methods related to the blacs parallel environment
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_scale_and_add(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b).
subroutine, public cp_cfm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, c_first_row)
Performs one of the matrix-matrix operations: matrix_c = alpha * op1( matrix_a ) * op2( matrix_b ) + ...
subroutine, public cp_cfm_rot_rows(matrix, irow, jrow, cs, sn)
Applies a planar rotation defined by cs and sn to the i'th and j'th rows.
subroutine, public cp_cfm_schur_product(matrix_a, matrix_b, matrix_c)
Computes the element-wise (Schur) product of two matrices: C = A \circ B .
subroutine, public cp_cfm_column_scale(matrix_a, scaling)
Scales columns of the full matrix by corresponding factors.
subroutine, public cp_cfm_rot_cols(matrix, icol, jcol, cs, sn)
Applies a planar rotation defined by cs and sn to the i'th and j'th columnns.
subroutine, public cp_cfm_trace(matrix_a, matrix_b, trace)
Returns the trace of matrix_a^T matrix_b, i.e sum_{i,j}(matrix_a(i,j)*matrix_b(i,j)) .
used for collecting diagonalization schemes available for cp_cfm_type
subroutine, public cp_cfm_heevd(matrix, eigenvectors, eigenvalues)
Perform a diagonalisation of a complex matrix.
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
Extract a sub-matrix from the full matrix: op(target_m)(1:n_rows,1:n_cols) = fm(start_row:start_row+n...
subroutine, public cp_cfm_get_element(matrix, irow_global, icol_global, alpha)
Get the matrix element by its global index.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_cfm_set_element(matrix, irow_global, icol_global, alpha)
Set the matrix element (irow_global,icol_global) of the full matrix to alpha.
subroutine, public cp_fm_to_cfm(msourcer, msourcei, mtarget)
Construct a complex full matrix by taking its real and imaginary parts from two separate real-value f...
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
subroutine, public cp_cfm_set_submatrix(matrix, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
Set a sub-matrix of the full matrix: matrix(start_row:start_row+n_rows,start_col:start_col+n_cols) = ...
subroutine, public cp_cfm_set_all(matrix, alpha, beta)
Set all elements of the full matrix to alpha. Besides, set all diagonal matrix elements to beta (if g...
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
Routines to handle the external control of CP2K.
subroutine, public external_control(should_stop, flag, globenv, target_time, start_time, force_check)
External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype command is sent the progr...
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_pdgeqpf(matrix, tau, nrow, ncol, first_row, first_col)
compute a QR factorization with column pivoting of a M-by-N distributed matrix sub( A ) = A(IA:IA+M-1...
real(kind=dp) function, public cp_fm_frobenius_norm(matrix_a)
computes the Frobenius norm of matrix_a
subroutine, public cp_fm_transpose(matrix, matrixt)
transposes a matrix matrixt = matrix ^ T
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
subroutine, public cp_fm_scale(alpha, matrix_a)
scales a matrix matrix_a = alpha * matrix_b
subroutine, public cp_fm_triangular_multiply(triangular_matrix, matrix_b, side, transpose_tr, invert_tr, uplo_tr, unit_diag_tr, n_rows, n_cols, alpha)
multiplies in place by a triangular matrix: matrix_b = alpha op(triangular_matrix) matrix_b or (if si...
subroutine, public cp_fm_pdorgqr(matrix, tau, nrow, first_row, first_col)
generates an M-by-N real distributed matrix Q denoting A(IA:IA+M-1,JA:JA+N-1) with orthonormal column...
various cholesky decomposition related routines
subroutine, public cp_fm_cholesky_decompose(matrix, n, info_out)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
subroutine, public cp_fm_syevd(matrix, eigenvectors, eigenvalues, info)
Computes all eigenvalues and vectors of a real symmetric matrix significantly faster than syevx,...
subroutine, public choose_eigv_solver(matrix, eigenvectors, eigenvalues, info)
Choose the Eigensolver depending on which library is available ELPA seems to be unstable for small sy...
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_get(fmstruct, para_env, context, descriptor, ncol_block, nrow_block, nrow_global, ncol_global, first_p_pos, row_indices, col_indices, nrow_local, ncol_local, nrow_locals, ncol_locals, local_leading_dimension)
returns the values of various attributes of the matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_get_element(matrix, irow_global, icol_global, alpha, local)
returns an element of a fm this value is valid on every cpu using this call is expensive
subroutine, public cp_fm_set_submatrix(fm, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
sets a submatrix of a full matrix fm(start_row:start_row+n_rows,start_col:start_col+n_cols) = alpha*o...
subroutine, public cp_fm_maxabsrownorm(matrix, a_max)
find the maximum over the rows of the sum of the absolute values of the elements of a given row = || ...
subroutine, public cp_fm_to_fm_submat(msource, mtarget, nrow, ncol, s_firstrow, s_firstcol, t_firstrow, t_firstcol)
copy just a part ot the matrix
subroutine, public cp_fm_maxabsval(matrix, a_max, ir_max, ic_max)
find the maximum absolute value of the matrix element maxval(abs(matrix))
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
subroutine, public cp_fm_init_random(matrix, ncol, start_col)
fills a matrix with random numbers
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
sums arrays of real/complex numbers with much reduced round-off as compared to a naive implementation...
Defines the basic variable types.
integer, parameter, public dp
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public gaussi
real(kind=dp), parameter, public twopi
complex(kind=dp), parameter, public z_zero
Routines for calculating a complex matrix exponential.
subroutine, public exp_pade_real(exp_h, matrix, nsquare, npade)
exponential of a real matrix, calculated using pade approximation together with scaling and squaring
subroutine, public get_nsquare_norder(norm, nsquare, norder, eps_exp, method, do_emd)
optimization function for pade/taylor order and number of squaring steps
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
Localization methods such as 2x2 Jacobi rotations Steepest Decents Conjugate Gradient.
subroutine, public approx_l1_norm_sd(c, iterations, eps, converged, sweeps)
...
subroutine, public rotate_orbitals(rmat, vectors)
...
subroutine, public cardoso_souloumiac(weights, zij, max_iter, eps_localization, sweeps, out_each, vectors)
Achieves minimisation of the spread functional by simultaneous diagonalisation with Jacobi rotations ...
subroutine, public jacobi_rotations(weights, zij, vectors, para_env, max_iter, eps_localization, sweeps, out_each, target_time, start_time, restricted)
wrapper for the jacobi routines, should be removed if jacobi_rot_para can deal with serial para_envs.
subroutine, public zij_matrix(vectors, op_sm_set, zij_fm_set)
...
subroutine, public direct_mini(weights, zij, vectors, max_iter, eps_localization, iterations)
use the exponential parametrization as described in to perform a direct mini Gerd Berghold et al....
subroutine, public initialize_weights(cell, weights)
...
subroutine, public crazy_rotations(weights, zij, vectors, max_iter, max_crazy_angle, crazy_scale, crazy_use_diag, eps_localization, iterations, converged)
yet another crazy try, computes the angles needed to rotate the orbitals first and rotates them all a...
subroutine, public scdm_qrfact(vectors)
...
subroutine, public cardoso_souloumiac_pipek(zij, vec, sweeps, max_iter, eps, out_each)
Pipek-Mezey version of the Cardoso-Souloumiac PADE algorithm for complex-valued matrices.
subroutine, public jacobi_cg_edf_ls(para_env, weights, zij, vectors, max_iter, eps_localization, iter, out_each, nextra, do_cg, nmo, vectors_2, mos_guess)
combine jacobi rotations (serial) and conjugate gradient with golden section line search for partiall...
Exchange and Correlation functional calculations.
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
Represent a complex full matrix.
keeps the information about the structure of a full matrix
stores all the informations relevant to an mpi environment