44#include "./base/base_uses.f90"
64 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_param_init_linpot'
66 INTEGER :: acol, arow, handle, iatom, ikind, n, &
68 INTEGER,
DIMENSION(:),
POINTER :: blk_sizes_pri, col_blk_size, row_blk_size
69 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_v_terms
70 REAL(
dp),
DIMENSION(:, :, :),
POINTER :: v_blocks
76 CALL timeset(routinen, handle)
80 dft_control=dft_control, &
81 particle_set=particle_set, &
84 IF (dft_control%nspins /= 1) cpabort(
"open shell not yet implemented")
87 ALLOCATE (row_blk_size(natoms), col_blk_size(natoms))
89 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
91 col_blk_size(iatom) = nterms
96 row_blk_size = blk_sizes_pri**2
98 name=
"PAO matrix_V_terms", &
99 dist=pao%diag_distribution, &
101 row_blk_size=row_blk_size, &
102 col_blk_size=col_blk_size)
104 DEALLOCATE (row_blk_size, col_blk_size)
112 iatom = arow; cpassert(arow == acol)
113 nterms =
SIZE(block_v_terms, 2)
114 IF (nterms == 0) cycle
115 n = blk_sizes_pri(iatom)
116 cpassert(n*n ==
SIZE(block_v_terms, 1))
117 ALLOCATE (v_blocks(n, n, nterms))
118 CALL linpot_calc_terms(pao, qs_env, iatom, v_blocks)
119 block_v_terms = reshape(v_blocks, [n*n, nterms])
120 DEALLOCATE (v_blocks)
125 CALL pao_param_linpot_regularizer(pao)
127 IF (pao%precondition)
THEN
128 CALL pao_param_linpot_preconditioner(pao)
133 CALL timestop(handle)
140 SUBROUTINE pao_param_linpot_regularizer(pao)
143 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_param_linpot_regularizer'
145 INTEGER :: acol, arow, handle, i, iatom, j, k, &
147 INTEGER,
DIMENSION(:),
POINTER :: blk_sizes_nterms
150 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: s_evals
151 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: s, s_evecs
152 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_r, v_terms
155 CALL timeset(routinen, handle)
157 IF (pao%iw > 0)
WRITE (pao%iw, *)
"PAO| Building linpot regularizer"
159 CALL dbcsr_get_info(pao%matrix_V_terms, col_blk_size=blk_sizes_nterms)
163 template=pao%matrix_V_terms, &
165 row_blk_size=blk_sizes_nterms, &
166 col_blk_size=blk_sizes_nterms, &
176 iatom = arow; cpassert(arow == acol)
177 CALL dbcsr_get_block_p(matrix=pao%matrix_V_terms, row=iatom, col=iatom, block=v_terms, found=found)
178 cpassert(
ASSOCIATED(v_terms))
179 nterms =
SIZE(v_terms, 2)
180 IF (nterms == 0) cycle
183 ALLOCATE (s(nterms, nterms))
184 s(:, :) = matmul(transpose(v_terms), v_terms)
187 ALLOCATE (s_evals(nterms), s_evecs(nterms, nterms))
193 v = pao%linpot_regu_delta/s_evals(k)
194 w = pao%linpot_regu_strength*min(1.0_dp, abs(v))
197 block_r(i, j) = block_r(i, j) + w*s_evecs(i, k)*s_evecs(j, k)
203 DEALLOCATE (s, s_evals, s_evecs)
208 CALL timestop(handle)
209 END SUBROUTINE pao_param_linpot_regularizer
215 SUBROUTINE pao_param_linpot_preconditioner(pao)
218 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_param_linpot_preconditioner'
220 INTEGER :: acol, arow, handle, i, iatom, j, k, &
222 INTEGER,
DIMENSION(:),
POINTER :: blk_sizes_nterms
224 REAL(
dp) :: eval_capped
225 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: s_evals
226 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: s, s_evecs
227 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_precon, block_precon_inv, &
231 CALL timeset(routinen, handle)
233 IF (pao%iw > 0)
WRITE (pao%iw, *)
"PAO| Building linpot preconditioner"
235 CALL dbcsr_get_info(pao%matrix_V_terms, col_blk_size=blk_sizes_nterms)
238 template=pao%matrix_V_terms, &
240 row_blk_size=blk_sizes_nterms, &
241 col_blk_size=blk_sizes_nterms, &
242 name=
"PAO matrix_precon")
245 CALL dbcsr_create(pao%matrix_precon_inv, template=pao%matrix_precon, name=
"PAO matrix_precon_inv")
253 iatom = arow; cpassert(arow == acol)
254 nterms =
SIZE(block_v_terms, 2)
255 IF (nterms == 0) cycle
257 CALL dbcsr_get_block_p(matrix=pao%matrix_precon, row=iatom, col=iatom, block=block_precon, found=found)
258 CALL dbcsr_get_block_p(matrix=pao%matrix_precon_inv, row=iatom, col=iatom, block=block_precon_inv, found=found)
259 cpassert(
ASSOCIATED(block_precon))
260 cpassert(
ASSOCIATED(block_precon_inv))
262 ALLOCATE (s(nterms, nterms))
263 s(:, :) = matmul(transpose(block_v_terms), block_v_terms)
266 ALLOCATE (s_evals(nterms), s_evecs(nterms, nterms))
271 block_precon = 0.0_dp
272 block_precon_inv = 0.0_dp
274 eval_capped = max(pao%linpot_precon_delta, s_evals(k))
277 block_precon(i, j) = block_precon(i, j) + s_evecs(i, k)*s_evecs(j, k)/sqrt(eval_capped)
278 block_precon_inv(i, j) = block_precon_inv(i, j) + s_evecs(i, k)*s_evecs(j, k)*sqrt(eval_capped)
283 DEALLOCATE (s, s_evecs, s_evals)
288 CALL timestop(handle)
289 END SUBROUTINE pao_param_linpot_preconditioner
301 IF (pao%precondition)
THEN
318 INTEGER,
INTENT(IN) :: ikind
319 INTEGER,
INTENT(OUT) :: nparams
321 INTEGER :: pao_basis_size
323 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
325 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
328 basis_set=basis_set, &
329 pao_basis_size=pao_basis_size)
331 IF (pao_basis_size == basis_set%nsgf)
THEN
335 SELECT CASE (pao%parameterization)
341 cpabort(
"unknown parameterization")
360 LOGICAL,
INTENT(IN) :: gradient
361 REAL(
dp),
INTENT(INOUT),
OPTIONAL :: penalty
362 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT),
OPTIONAL :: forces
364 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_calc_AB_linpot'
370 CALL timeset(routinen, handle)
372 CALL dbcsr_create(matrix_u, matrix_type=
"N", dist=pao%diag_distribution, template=matrix_s(1)%matrix)
378 CALL pao_calc_u_linpot(pao, qs_env, matrix_u, matrix_m, pao%matrix_G, penalty, forces)
381 CALL pao_calc_u_linpot(pao, qs_env, matrix_u, penalty=penalty)
386 CALL timestop(handle)
399 SUBROUTINE pao_calc_u_linpot(pao, qs_env, matrix_U, matrix_M, matrix_G, penalty, forces)
403 TYPE(
dbcsr_type),
OPTIONAL :: matrix_m, matrix_g
404 REAL(
dp),
INTENT(INOUT),
OPTIONAL :: penalty
405 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT),
OPTIONAL :: forces
407 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_calc_U_linpot'
409 INTEGER :: acol, arow, handle, iatom, kterm, n, &
412 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: gaps
413 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: evals
414 REAL(
dp),
DIMENSION(:),
POINTER :: vec_m2, vec_v
415 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_g, block_m1, block_m2, block_r, &
416 block_u, block_v, block_v_terms, &
418 REAL(
dp),
DIMENSION(:, :, :),
POINTER :: m_blocks
419 REAL(kind=
dp) :: regu_energy
423 CALL timeset(routinen, handle)
425 cpassert(
PRESENT(matrix_g) .EQV.
PRESENT(matrix_m))
428 ALLOCATE (gaps(natoms), evals(10, natoms))
430 gaps(:) = huge(1.0_dp)
437 iatom = arow; cpassert(arow == acol)
438 CALL dbcsr_get_block_p(matrix=pao%matrix_R, row=iatom, col=iatom, block=block_r, found=found)
439 CALL dbcsr_get_block_p(matrix=matrix_u, row=iatom, col=iatom, block=block_u, found=found)
440 cpassert(
ASSOCIATED(block_r) .AND.
ASSOCIATED(block_u))
444 ALLOCATE (vec_v(n*n))
446 CALL dbcsr_get_block_p(matrix=pao%matrix_V_terms, row=iatom, col=iatom, block=block_v_terms, found=found)
447 cpassert(
ASSOCIATED(block_v_terms))
448 nterms =
SIZE(block_v_terms, 2)
451 vec_v = matmul(block_v_terms, block_x(:, 1))
453 block_v(1:n, 1:n) => vec_v(:)
456 IF (maxval(abs(block_v - transpose(block_v))/max(1.0_dp, maxval(abs(block_v)))) > 1e-12)
THEN
457 cpabort(
"block_V not symmetric")
459 block_v = 0.5_dp*(block_v + transpose(block_v))
463 IF (
PRESENT(penalty) .AND. nterms > 0)
THEN
464 regu_energy = regu_energy + dot_product(block_x(:, 1), matmul(block_r, block_x(:, 1)))
468 gap=gaps(iatom), evals=evals(:, iatom))
470 IF (
PRESENT(matrix_g))
THEN
471 cpassert(
PRESENT(matrix_m))
472 CALL dbcsr_get_block_p(matrix=matrix_m, row=iatom, col=iatom, block=block_m1, found=found)
475 IF (
ASSOCIATED(block_m1) .AND.
SIZE(block_v_terms) > 0)
THEN
476 ALLOCATE (vec_m2(n*n))
477 block_m2(1:n, 1:n) => vec_m2(:)
480 m1=block_m1, g=block_m2, gap=gaps(iatom), evals=evals(:, iatom))
481 IF (maxval(abs(block_m2 - transpose(block_m2))) > 1e-14_dp)
THEN
482 cpabort(
"matrix not symmetric")
486 IF (
PRESENT(matrix_g))
THEN
487 CALL dbcsr_get_block_p(matrix=matrix_g, row=iatom, col=iatom, block=block_g, found=found)
488 cpassert(
ASSOCIATED(block_g))
489 block_g(:, 1) = matmul(vec_m2, block_v_terms)
490 IF (
PRESENT(penalty))
THEN
491 block_g = block_g + 2.0_dp*matmul(block_r, block_x)
496 IF (
PRESENT(forces))
THEN
497 ALLOCATE (m_blocks(n, n, nterms))
499 m_blocks(:, :, kterm) = block_m2*block_x(kterm, 1)
501 CALL linpot_calc_forces(pao, qs_env, iatom=iatom, m_blocks=m_blocks, forces=forces)
502 DEALLOCATE (m_blocks)
512 IF (
PRESENT(penalty))
THEN
514 CALL group%sum(penalty)
515 CALL group%sum(regu_energy)
516 penalty = penalty + regu_energy
520 IF (.NOT.
PRESENT(forces))
THEN
522 CALL group%sum(evals)
523 IF (pao%iw_fockev > 0)
THEN
525 WRITE (pao%iw_fockev, *)
"PAO| atom:", iatom,
" fock evals around gap:", evals(:, iatom)
531 IF (pao%iw_gap > 0)
THEN
533 WRITE (pao%iw_gap, *)
"PAO| atom:", iatom,
" fock gap:", gaps(iatom)
537 IF (pao%iw > 0)
WRITE (pao%iw, *)
"PAO| linpot regularization energy:", regu_energy
538 IF (pao%iw > 0)
WRITE (pao%iw,
"(A,E20.10,A,T71,I10)")
" PAO| min_gap:", minval(gaps),
" for atom:", minloc(gaps)
541 DEALLOCATE (gaps, evals)
542 CALL timestop(handle)
544 END SUBROUTINE pao_calc_u_linpot
553 SUBROUTINE linpot_calc_terms(pao, qs_env, iatom, V_blocks)
556 INTEGER,
INTENT(IN) :: iatom
557 REAL(
dp),
DIMENSION(:, :, :),
INTENT(OUT) :: v_blocks
559 SELECT CASE (pao%parameterization)
565 cpabort(
"unknown parameterization")
568 END SUBROUTINE linpot_calc_terms
578 SUBROUTINE linpot_calc_forces(pao, qs_env, iatom, M_blocks, forces)
581 INTEGER,
INTENT(IN) :: iatom
582 REAL(
dp),
DIMENSION(:, :, :),
INTENT(IN) :: m_blocks
583 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT) :: forces
585 SELECT CASE (pao%parameterization)
591 cpabort(
"unknown parameterization")
594 END SUBROUTINE linpot_calc_forces
605 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_param_initguess_linpot'
607 INTEGER :: acol, arow, handle, i, iatom, j, k, n, &
609 INTEGER,
DIMENSION(:),
POINTER :: pri_basis_size
612 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: s_evals
613 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: s, s_evecs, s_inv
614 REAL(
dp),
DIMENSION(:),
POINTER :: v_guess_vec
615 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_x, v_guess, v_terms
618 CALL timeset(routinen, handle)
627 iatom = arow; cpassert(arow == acol)
628 CALL dbcsr_get_block_p(matrix=pao%matrix_V_terms, row=iatom, col=iatom, block=v_terms, found=found)
629 cpassert(
ASSOCIATED(v_terms))
630 nterms =
SIZE(v_terms, 2)
631 IF (nterms == 0) cycle
634 n = pri_basis_size(iatom)
635 ALLOCATE (v_guess_vec(n*n))
636 v_guess(1:n, 1:n) => v_guess_vec
640 ALLOCATE (s(nterms, nterms))
641 s(:, :) = matmul(transpose(v_terms), v_terms)
644 ALLOCATE (s_evals(nterms), s_evecs(nterms, nterms))
649 ALLOCATE (s_inv(nterms, nterms))
652 w = s_evals(k)/(s_evals(k)**2 + pao%linpot_init_delta)
655 s_inv(i, j) = s_inv(i, j) + w*s_evecs(i, k)*s_evecs(j, k)
661 block_x(:, 1) = matmul(matmul(s_inv, transpose(v_terms)), v_guess_vec)
664 DEALLOCATE (v_guess_vec, s, s_evecs, s_evals, s_inv)
669 CALL timestop(handle)
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
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_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_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_reserve_diag_blocks(matrix)
Reserves all diagonal blocks.
Types needed for a linear scaling quickstep SCF run based on the density matrix.
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
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...
Interface to the message passing library MPI.
Full parametrization of Fock matrix, ie. the identity parametrization.
subroutine, public linpot_full_calc_terms(v_blocks)
Builds potential terms.
subroutine, public linpot_full_count_terms(qs_env, ikind, nterms)
Count number of terms for given atomic kind.
Rotationally invariant parametrization of Fock matrix.
subroutine, public linpot_rotinv_calc_forces(qs_env, iatom, m_blocks, forces)
Calculate force contribution from rotinv parametrization.
subroutine, public linpot_rotinv_calc_terms(qs_env, iatom, v_blocks)
Calculate all potential terms of the rotinv parametrization.
subroutine, public linpot_rotinv_count_terms(qs_env, ikind, nterms)
Count number of terms for given atomic kind.
Common framework for using eigenvectors of a Fock matrix as PAO basis.
subroutine, public pao_calc_u_block_fock(pao, iatom, v, u, penalty, gap, evals, m1, g)
Calculate new matrix U and optinally its gradient G.
Common framework for a linear parametrization of the potential.
subroutine, public pao_param_finalize_linpot(pao)
Finalize the linear potential parametrization.
subroutine, public pao_param_init_linpot(pao, qs_env)
Initialize the linear potential parametrization.
subroutine, public pao_calc_ab_linpot(pao, qs_env, ls_scf_env, gradient, penalty, forces)
Takes current matrix_X and calculates the matrices A and B.
subroutine, public pao_param_count_linpot(pao, qs_env, ikind, nparams)
Returns the number of potential terms for given atomic kind.
subroutine, public pao_param_initguess_linpot(pao, qs_env)
Calculate initial guess for matrix_X.
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.
Define the data structure for the particle information.
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, mimic, 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_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, 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, matrix_vhxc, 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, xcint_weights, 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, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_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, harris_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, eeq, rhs, do_rixs, tb_tblite)
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, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, 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_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, hund_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, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.