14 USE dbcsr_api,
ONLY: &
15 dbcsr_create, dbcsr_get_block_p, dbcsr_get_info, dbcsr_iterator_blocks_left, &
16 dbcsr_iterator_next_block, dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, &
17 dbcsr_p_type, dbcsr_release, dbcsr_reserve_diag_blocks, dbcsr_set, dbcsr_type
29 #include "./base/base_uses.f90"
35 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'pao_param_exp'
48 TYPE(pao_env_type),
POINTER :: pao
49 TYPE(qs_environment_type),
POINTER :: qs_env
51 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_param_init_exp'
53 INTEGER :: acol, arow, handle, iatom, n
55 REAL(
dp),
DIMENSION(:),
POINTER :: h_evals
56 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_h, block_h0, block_n, block_u0, &
58 TYPE(dbcsr_iterator_type) :: iter
59 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
61 CALL timeset(routinen, handle)
66 CALL dbcsr_create(pao%matrix_U0, &
67 name=
"PAO matrix_U0", &
69 dist=pao%diag_distribution, &
70 template=matrix_s(1)%matrix)
71 CALL dbcsr_reserve_diag_blocks(pao%matrix_U0)
76 CALL dbcsr_iterator_start(iter, pao%matrix_U0)
77 DO WHILE (dbcsr_iterator_blocks_left(iter))
78 CALL dbcsr_iterator_next_block(iter, arow, acol, block_u0)
79 iatom = arow; cpassert(arow == acol)
80 CALL dbcsr_get_block_p(matrix=pao%matrix_H0, row=iatom, col=iatom, block=block_h0, found=found)
81 CALL dbcsr_get_block_p(matrix=pao%matrix_N_diag, row=iatom, col=iatom, block=block_n, found=found)
82 cpassert(
ASSOCIATED(block_h0) .AND.
ASSOCIATED(block_n))
85 ALLOCATE (block_v0(n, n))
89 ALLOCATE (block_h(n, n))
90 block_h = matmul(matmul(block_n, block_h0 + block_v0), block_n)
93 ALLOCATE (h_evecs(n, n), h_evals(n))
100 DEALLOCATE (block_h, h_evecs, h_evals, block_v0)
102 CALL dbcsr_iterator_stop(iter)
105 IF (pao%precondition) &
106 cpabort(
"PAO preconditioning not supported for selected parametrization.")
108 CALL timestop(handle)
116 TYPE(pao_env_type),
POINTER :: pao
118 CALL dbcsr_release(pao%matrix_U0)
129 TYPE(qs_environment_type),
POINTER :: qs_env
130 INTEGER,
INTENT(IN) :: ikind
131 INTEGER,
INTENT(OUT) :: nparams
133 INTEGER :: cols, pao_basis_size, pri_basis_size, &
135 TYPE(gto_basis_set_type),
POINTER :: basis_set
136 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
138 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
140 basis_set=basis_set, &
141 pao_basis_size=pao_basis_size)
142 pri_basis_size = basis_set%nsgf
145 rows = pao_basis_size
146 cols = pri_basis_size - pao_basis_size
156 TYPE(pao_env_type),
POINTER :: pao
158 CALL dbcsr_set(pao%matrix_X, 0.0_dp)
170 TYPE(pao_env_type),
POINTER :: pao
171 TYPE(qs_environment_type),
POINTER :: qs_env
172 TYPE(ls_scf_env_type),
TARGET :: ls_scf_env
173 LOGICAL,
INTENT(IN) :: gradient
175 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_calc_AB_exp'
178 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
179 TYPE(dbcsr_type) :: matrix_m, matrix_u
181 CALL timeset(routinen, handle)
183 CALL dbcsr_create(matrix_u, matrix_type=
"N", dist=pao%diag_distribution, template=matrix_s(1)%matrix)
184 CALL dbcsr_reserve_diag_blocks(matrix_u)
189 CALL pao_calc_u_exp(pao, matrix_u, matrix_m, pao%matrix_G)
190 CALL dbcsr_release(matrix_m)
192 CALL pao_calc_u_exp(pao, matrix_u)
196 CALL dbcsr_release(matrix_u)
197 CALL timestop(handle)
207 SUBROUTINE pao_calc_u_exp(pao, matrix_U, matrix_M, matrix_G)
208 TYPE(pao_env_type),
POINTER :: pao
209 TYPE(dbcsr_type) :: matrix_u
210 TYPE(dbcsr_type),
OPTIONAL :: matrix_m, matrix_g
212 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_calc_U_exp'
215 COMPLEX(dp),
DIMENSION(:),
POINTER :: evals
216 COMPLEX(dp),
DIMENSION(:, :),
POINTER :: block_d, evecs
217 INTEGER :: acol, arow, handle, i, iatom, j, k, m, &
219 INTEGER,
DIMENSION(:),
POINTER :: blk_sizes_pao, blk_sizes_pri
221 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_g, block_g_full, block_m, &
222 block_tmp, block_u, block_u0, block_x, &
224 TYPE(dbcsr_iterator_type) :: iter
226 CALL timeset(routinen, handle)
228 CALL dbcsr_get_info(pao%matrix_Y, row_blk_size=blk_sizes_pri, col_blk_size=blk_sizes_pao)
234 CALL dbcsr_iterator_start(iter, pao%matrix_X)
235 DO WHILE (dbcsr_iterator_blocks_left(iter))
236 CALL dbcsr_iterator_next_block(iter, arow, acol, block_x)
237 iatom = arow; cpassert(arow == acol)
238 CALL dbcsr_get_block_p(matrix=matrix_u, row=iatom, col=iatom, block=block_u, found=found)
239 cpassert(
ASSOCIATED(block_u))
240 CALL dbcsr_get_block_p(matrix=pao%matrix_U0, row=iatom, col=iatom, block=block_u0, found=found)
241 cpassert(
ASSOCIATED(block_u0))
243 n = blk_sizes_pri(iatom)
244 m = blk_sizes_pao(iatom)
245 nparams =
SIZE(block_x, 1)
249 ALLOCATE (block_x_full(n, n))
250 block_x_full(:, :) = 0.0_dp
252 block_x_full(mod(i - 1, m) + 1, m + (i - 1)/m + 1) = +block_x(i, 1)
253 block_x_full(m + (i - 1)/m + 1, mod(i - 1, m) + 1) = -block_x(i, 1)
257 ALLOCATE (evals(n), evecs(n, n))
258 CALL diag_antisym(block_x_full, evecs, evals)
261 block_u(:, :) = 0.0_dp
265 block_u(i, j) = block_u(i, j) + real(exp(evals(k))*evecs(i, k)*conjg(evecs(j, k)),
dp)
270 block_u = matmul(block_u0, block_u)
273 IF (
PRESENT(matrix_g))
THEN
274 cpassert(
PRESENT(matrix_m))
276 CALL dbcsr_get_block_p(matrix=pao%matrix_G, row=iatom, col=iatom, block=block_g, found=found)
277 cpassert(
ASSOCIATED(block_g))
278 CALL dbcsr_get_block_p(matrix=matrix_m, row=iatom, col=iatom, block=block_m, found=found)
281 ALLOCATE (block_d(n, n), block_tmp(n, n), block_g_full(n, n))
284 denom = evals(i) - evals(j)
286 block_d(i, i) = exp(evals(i))
287 ELSE IF (abs(denom) > 1e-10_dp)
THEN
288 block_d(i, j) = (exp(evals(i)) - exp(evals(j)))/denom
290 block_d(i, j) = 1.0_dp
295 IF (
ASSOCIATED(block_m))
THEN
296 block_tmp = matmul(transpose(block_u0), block_m)
300 block_g_full = fold_derivatives(block_tmp, block_d, evecs)
304 block_g(i, 1) = 2.0_dp*block_g_full(mod(i - 1, m) + 1, m + (i - 1)/m + 1)
307 DEALLOCATE (block_d, block_tmp, block_g_full)
310 DEALLOCATE (block_x_full, evals, evecs)
313 CALL dbcsr_iterator_stop(iter)
316 CALL timestop(handle)
317 END SUBROUTINE pao_calc_u_exp
326 FUNCTION fold_derivatives(M, D, R)
RESULT(G)
327 REAL(
dp),
DIMENSION(:, :),
INTENT(IN) :: m
328 COMPLEX(dp),
DIMENSION(:, :),
INTENT(IN) :: d, r
329 REAL(
dp),
DIMENSION(SIZE(M, 1), SIZE(M, 1)) :: g
331 COMPLEX(dp),
DIMENSION(:, :),
POINTER :: f, rf, rm, rmr
333 REAL(
dp),
DIMENSION(:, :),
POINTER :: rfr
337 ALLOCATE (rm(n, n), rmr(n, n), f(n, n), rf(n, n), rfr(n, n))
339 rm = matmul(transpose(conjg(r)), transpose(m))
343 rfr = real(matmul(rf, transpose(conjg(r))),
dp)
346 g = 0.5_dp*(transpose(rfr) - rfr)
348 DEALLOCATE (rm, rmr, f, rf, rfr)
349 END FUNCTION fold_derivatives
357 SUBROUTINE diag_antisym(matrix, evecs, evals)
358 REAL(
dp),
DIMENSION(:, :) :: matrix
359 COMPLEX(dp),
DIMENSION(:, :) :: evecs
360 COMPLEX(dp),
DIMENSION(:) :: evals
362 COMPLEX(dp),
DIMENSION(:, :),
POINTER :: matrix_c
364 REAL(
dp),
DIMENSION(:),
POINTER :: evals_r
366 IF (maxval(abs(matrix + transpose(matrix))) > 1e-14_dp) cpabort(
"Expected anti-symmetric matrix")
368 ALLOCATE (matrix_c(n, n), evals_r(n))
370 matrix_c = cmplx(0.0_dp, -matrix, kind=
dp)
371 CALL zheevd_wrapper(matrix_c, evecs, evals_r)
372 evals = cmplx(0.0_dp, evals_r, kind=
dp)
374 DEALLOCATE (matrix_c, evals_r)
375 END SUBROUTINE diag_antisym
383 SUBROUTINE zheevd_wrapper(matrix, eigenvectors, eigenvalues)
384 COMPLEX(dp),
DIMENSION(:, :) :: matrix, eigenvectors
385 REAL(
dp),
DIMENSION(:) :: eigenvalues
387 CHARACTER(len=*),
PARAMETER :: routinen =
'zheevd_wrapper'
389 COMPLEX(KIND=dp),
DIMENSION(:),
POINTER :: work
390 COMPLEX(KIND=dp),
DIMENSION(:, :),
POINTER :: a
391 INTEGER :: handle, info, liwork, lrwork, lwork, n
392 INTEGER,
DIMENSION(:),
POINTER :: iwork
393 REAL(kind=
dp),
DIMENSION(:),
POINTER :: rwork
395 CALL timeset(routinen, handle)
397 IF (
SIZE(matrix, 1) /=
SIZE(matrix, 2)) cpabort(
"expected square matrix")
398 IF (maxval(abs(matrix - conjg(transpose(matrix)))) > 1e-14_dp) cpabort(
"Expect hermitian matrix")
401 ALLOCATE (iwork(1), rwork(1), work(1), a(n, n))
409 CALL zheevd(
'V',
'U', n, a(1, 1), n, eigenvalues(1), &
410 work(1), lwork, rwork(1), lrwork, iwork(1), liwork, info)
411 lwork = int(real(work(1),
dp))
412 lrwork = int(real(rwork(1),
dp))
415 DEALLOCATE (iwork, rwork, work)
416 ALLOCATE (iwork(liwork))
418 ALLOCATE (rwork(lrwork))
420 ALLOCATE (work(lwork))
421 work(:) = cmplx(0.0_dp, 0.0_dp, kind=
dp)
423 CALL zheevd(
'V',
'U', n, a(1, 1), n, eigenvalues(1), &
424 work(1), lwork, rwork(1), lrwork, iwork(1), liwork, info)
428 IF (info /= 0) cpabort(
"diagonalization failed")
430 DEALLOCATE (iwork, rwork, work, a)
432 CALL timestop(handle)
434 END SUBROUTINE zheevd_wrapper
Types needed for a linear scaling quickstep SCF run based on the density matrix.
Defines the basic variable types.
integer, parameter, public dp
Collection of simple mathematical functions and subroutines.
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...
Original matrix exponential parametrization.
subroutine, public pao_calc_ab_exp(pao, qs_env, ls_scf_env, gradient)
Takes current matrix_X and calculates the matrices A and B.
subroutine, public pao_param_finalize_exp(pao)
Finalize exponential parametrization.
subroutine, public pao_param_initguess_exp(pao)
Fills matrix_X with an initial guess.
subroutine, public pao_param_init_exp(pao, qs_env)
Initialize matrix exponential parametrization.
subroutine, public pao_param_count_exp(qs_env, ikind, nparams)
Returns the number of parameters for given atomic kind.
Common routines for PAO parametrizations.
subroutine, public pao_calc_grad_lnv_wrt_u(qs_env, ls_scf_env, matrix_M_diag)
Helper routine, calculates partial derivative dE/dU.
subroutine, public pao_calc_ab_from_u(pao, qs_env, ls_scf_env, matrix_U_diag)
Takes current matrix_X and calculates the matrices A and B.
Factory routines for potentials used e.g. by pao_param_exp and pao_ml.
subroutine, public pao_guess_initial_potential(qs_env, iatom, block_V)
Makes an educated guess for the initial potential based on positions of neighboring atoms.
Types used by the PAO machinery.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_RI_aux_kp, matrix_s, matrix_s_RI_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, WannierCentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, rhs)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_r3d_rs_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, U_of_dft_plus_u, J_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, J0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.