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'
408 REAL(kind=
dp),
PARAMETER :: eps_block_v_sym = 1.0e-12_dp
410 INTEGER :: acol, arow, handle, iatom, kterm, n, &
413 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: gaps
414 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: evals
415 REAL(
dp),
DIMENSION(:),
POINTER :: vec_m2, vec_v
416 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_g, block_m1, block_m2, block_r, &
417 block_u, block_v, block_v_terms, &
419 REAL(
dp),
DIMENSION(:, :, :),
POINTER :: m_blocks
420 REAL(kind=
dp) :: regu_energy
424 CALL timeset(routinen, handle)
426 cpassert(
PRESENT(matrix_g) .EQV.
PRESENT(matrix_m))
429 ALLOCATE (gaps(natoms), evals(10, natoms))
431 gaps(:) = huge(1.0_dp)
438 iatom = arow; cpassert(arow == acol)
439 CALL dbcsr_get_block_p(matrix=pao%matrix_R, row=iatom, col=iatom, block=block_r, found=found)
440 CALL dbcsr_get_block_p(matrix=matrix_u, row=iatom, col=iatom, block=block_u, found=found)
441 cpassert(
ASSOCIATED(block_r) .AND.
ASSOCIATED(block_u))
445 ALLOCATE (vec_v(n*n))
447 CALL dbcsr_get_block_p(matrix=pao%matrix_V_terms, row=iatom, col=iatom, block=block_v_terms, found=found)
448 cpassert(
ASSOCIATED(block_v_terms))
449 nterms =
SIZE(block_v_terms, 2)
452 vec_v = matmul(block_v_terms, block_x(:, 1))
454 block_v(1:n, 1:n) => vec_v(:)
457 IF (maxval(abs(block_v - transpose(block_v))/max(1.0_dp, maxval(abs(block_v)))) > eps_block_v_sym)
THEN
458 cpabort(
"block_V not symmetric")
460 block_v = 0.5_dp*(block_v + transpose(block_v))
464 IF (
PRESENT(penalty) .AND. nterms > 0)
THEN
465 regu_energy = regu_energy + dot_product(block_x(:, 1), matmul(block_r, block_x(:, 1)))
469 gap=gaps(iatom), evals=evals(:, iatom))
471 IF (
PRESENT(matrix_g))
THEN
472 cpassert(
PRESENT(matrix_m))
473 CALL dbcsr_get_block_p(matrix=matrix_m, row=iatom, col=iatom, block=block_m1, found=found)
476 IF (
ASSOCIATED(block_m1) .AND.
SIZE(block_v_terms) > 0)
THEN
477 ALLOCATE (vec_m2(n*n))
478 block_m2(1:n, 1:n) => vec_m2(:)
481 m1=block_m1, g=block_m2, gap=gaps(iatom), evals=evals(:, iatom))
482 IF (maxval(abs(block_m2 - transpose(block_m2))) > 1e-14_dp)
THEN
483 cpabort(
"matrix not symmetric")
487 IF (
PRESENT(matrix_g))
THEN
488 CALL dbcsr_get_block_p(matrix=matrix_g, row=iatom, col=iatom, block=block_g, found=found)
489 cpassert(
ASSOCIATED(block_g))
490 block_g(:, 1) = matmul(vec_m2, block_v_terms)
491 IF (
PRESENT(penalty))
THEN
492 block_g = block_g + 2.0_dp*matmul(block_r, block_x)
497 IF (
PRESENT(forces))
THEN
498 ALLOCATE (m_blocks(n, n, nterms))
500 m_blocks(:, :, kterm) = block_m2*block_x(kterm, 1)
502 CALL linpot_calc_forces(pao, qs_env, iatom=iatom, m_blocks=m_blocks, forces=forces)
503 DEALLOCATE (m_blocks)
513 IF (
PRESENT(penalty))
THEN
515 CALL group%sum(penalty)
516 CALL group%sum(regu_energy)
517 penalty = penalty + regu_energy
521 IF (.NOT.
PRESENT(forces))
THEN
523 CALL group%sum(evals)
524 IF (pao%iw_fockev > 0)
THEN
526 WRITE (pao%iw_fockev, *)
"PAO| atom:", iatom,
" fock evals around gap:", evals(:, iatom)
532 IF (pao%iw_gap > 0)
THEN
534 WRITE (pao%iw_gap, *)
"PAO| atom:", iatom,
" fock gap:", gaps(iatom)
538 IF (pao%iw > 0)
WRITE (pao%iw, *)
"PAO| linpot regularization energy:", regu_energy
539 IF (pao%iw > 0)
WRITE (pao%iw,
"(A,E20.10,A,T71,I10)")
" PAO| min_gap:", minval(gaps),
" for atom:", minloc(gaps)
542 DEALLOCATE (gaps, evals)
543 CALL timestop(handle)
545 END SUBROUTINE pao_calc_u_linpot
554 SUBROUTINE linpot_calc_terms(pao, qs_env, iatom, V_blocks)
557 INTEGER,
INTENT(IN) :: iatom
558 REAL(
dp),
DIMENSION(:, :, :),
INTENT(OUT) :: v_blocks
560 SELECT CASE (pao%parameterization)
566 cpabort(
"unknown parameterization")
569 END SUBROUTINE linpot_calc_terms
579 SUBROUTINE linpot_calc_forces(pao, qs_env, iatom, M_blocks, forces)
582 INTEGER,
INTENT(IN) :: iatom
583 REAL(
dp),
DIMENSION(:, :, :),
INTENT(IN) :: m_blocks
584 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT) :: forces
586 SELECT CASE (pao%parameterization)
592 cpabort(
"unknown parameterization")
595 END SUBROUTINE linpot_calc_forces
606 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_param_initguess_linpot'
608 INTEGER :: acol, arow, handle, i, iatom, j, k, n, &
610 INTEGER,
DIMENSION(:),
POINTER :: pri_basis_size
613 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: s_evals
614 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: s, s_evecs, s_inv
615 REAL(
dp),
DIMENSION(:),
POINTER :: v_guess_vec
616 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_x, v_guess, v_terms
619 CALL timeset(routinen, handle)
628 iatom = arow; cpassert(arow == acol)
629 CALL dbcsr_get_block_p(matrix=pao%matrix_V_terms, row=iatom, col=iatom, block=v_terms, found=found)
630 cpassert(
ASSOCIATED(v_terms))
631 nterms =
SIZE(v_terms, 2)
632 IF (nterms == 0) cycle
635 n = pri_basis_size(iatom)
636 ALLOCATE (v_guess_vec(n*n))
637 v_guess(1:n, 1:n) => v_guess_vec
641 ALLOCATE (s(nterms, nterms))
642 s(:, :) = matmul(transpose(v_terms), v_terms)
645 ALLOCATE (s_evals(nterms), s_evecs(nterms, nterms))
650 ALLOCATE (s_inv(nterms, nterms))
653 w = s_evals(k)/(s_evals(k)**2 + pao%linpot_init_delta)
656 s_inv(i, j) = s_inv(i, j) + w*s_evecs(i, k)*s_evecs(j, k)
662 block_x(:, 1) = matmul(matmul(s_inv, transpose(v_terms)), v_guess_vec)
665 DEALLOCATE (v_guess_vec, s, s_evecs, s_evals, s_inv)
670 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.