(git:a0df33d)
Loading...
Searching...
No Matches
pao_methods.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Methods used by pao_main.F
10!> \author Ole Schuett
11! **************************************************************************************************
13 USE ao_util, ONLY: exp_radius
17 USE bibliography, ONLY: kolafa2004,&
18 kuhne2007,&
19 cite_reference
21 USE cp_dbcsr_api, ONLY: &
29 dbcsr_dot,&
36 USE dm_ls_scf_qs, ONLY: ls_scf_dm_to_ks,&
43 USE kinds, ONLY: default_path_length,&
44 dp
45 USE machine, ONLY: m_walltime
46 USE mathlib, ONLY: binomial,&
49 USE pao_ml, ONLY: pao_ml_forces
50 USE pao_model, ONLY: pao_model_forces,&
52 USE pao_param, ONLY: pao_calc_ab,&
54 USE pao_types, ONLY: pao_env_type
60 USE qs_kind_types, ONLY: get_qs_kind,&
68 USE qs_rho_types, ONLY: qs_rho_get,&
70
71!$ USE OMP_LIB, ONLY: omp_get_level
72#include "./base/base_uses.f90"
73
74 IMPLICIT NONE
75
76 PRIVATE
77
78 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pao_methods'
79
84 PUBLIC :: pao_test_convergence
87 PUBLIC :: pao_check_grad
88
89CONTAINS
90
91! **************************************************************************************************
92!> \brief Initialize qs kinds
93!> \param pao ...
94!> \param qs_env ...
95! **************************************************************************************************
96 SUBROUTINE pao_init_kinds(pao, qs_env)
97 TYPE(pao_env_type), POINTER :: pao
98 TYPE(qs_environment_type), POINTER :: qs_env
99
100 CHARACTER(len=*), PARAMETER :: routinen = 'pao_init_kinds'
101
102 CHARACTER(LEN=default_path_length) :: pao_model_file
103 INTEGER :: handle, i, ikind, pao_basis_size
104 TYPE(gto_basis_set_type), POINTER :: basis_set
105 TYPE(pao_descriptor_type), DIMENSION(:), POINTER :: pao_descriptors
106 TYPE(pao_potential_type), DIMENSION(:), POINTER :: pao_potentials
107 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
108
109 CALL timeset(routinen, handle)
110 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
111
112 DO ikind = 1, SIZE(qs_kind_set)
113 CALL get_qs_kind(qs_kind_set(ikind), &
114 basis_set=basis_set, &
115 pao_basis_size=pao_basis_size, &
116 pao_model_file=pao_model_file, &
118 pao_descriptors=pao_descriptors)
119
120 IF (pao_basis_size < 1) THEN
121 ! pao disabled for ikind, set pao_basis_size to size of primary basis
122 CALL set_qs_kind(qs_kind_set(ikind), pao_basis_size=basis_set%nsgf)
123 END IF
124
125 ! initialize radii of Gaussians to speedup screeing later on
126 DO i = 1, SIZE(pao_potentials)
127 pao_potentials(i)%beta_radius = exp_radius(0, pao_potentials(i)%beta, pao%eps_pgf, 1.0_dp)
128 END DO
129 DO i = 1, SIZE(pao_descriptors)
130 pao_descriptors(i)%beta_radius = exp_radius(0, pao_descriptors(i)%beta, pao%eps_pgf, 1.0_dp)
131 pao_descriptors(i)%screening_radius = exp_radius(0, pao_descriptors(i)%screening, pao%eps_pgf, 1.0_dp)
132 END DO
133
134 ! Load torch model.
135 IF (len_trim(pao_model_file) > 0) THEN
136 IF (.NOT. ALLOCATED(pao%models)) THEN
137 ALLOCATE (pao%models(SIZE(qs_kind_set)))
138 END IF
139 CALL pao_model_load(pao, qs_env, ikind, pao_model_file, pao%models(ikind))
140 END IF
141
142 END DO
143 CALL timestop(handle)
144 END SUBROUTINE pao_init_kinds
145
146! **************************************************************************************************
147!> \brief Prints a one line summary for each atom.
148!> \param pao ...
149! **************************************************************************************************
150 SUBROUTINE pao_print_atom_info(pao)
151 TYPE(pao_env_type), POINTER :: pao
152
153 INTEGER :: iatom, natoms
154 INTEGER, DIMENSION(:), POINTER :: pao_basis, param_cols, param_rows, &
155 pri_basis
156
157 CALL dbcsr_get_info(pao%matrix_Y, row_blk_size=pri_basis, col_blk_size=pao_basis)
158 cpassert(SIZE(pao_basis) == SIZE(pri_basis))
159 natoms = SIZE(pao_basis)
160
161 CALL dbcsr_get_info(pao%matrix_X, row_blk_size=param_rows, col_blk_size=param_cols)
162 cpassert(SIZE(param_rows) == natoms .AND. SIZE(param_cols) == natoms)
163
164 IF (pao%iw_atoms > 0) THEN
165 DO iatom = 1, natoms
166 WRITE (pao%iw_atoms, "(A,I7,T20,A,I3,T45,A,I3,T65,A,I3)") &
167 " PAO| atom: ", iatom, &
168 " prim_basis: ", pri_basis(iatom), &
169 " pao_basis: ", pao_basis(iatom), &
170 " pao_params: ", (param_cols(iatom)*param_rows(iatom))
171 END DO
172 END IF
173 END SUBROUTINE pao_print_atom_info
174
175! **************************************************************************************************
176!> \brief Constructs matrix_N and its inverse.
177!> \param pao ...
178!> \param qs_env ...
179! **************************************************************************************************
180 SUBROUTINE pao_build_orthogonalizer(pao, qs_env)
181 TYPE(pao_env_type), POINTER :: pao
182 TYPE(qs_environment_type), POINTER :: qs_env
183
184 CHARACTER(len=*), PARAMETER :: routinen = 'pao_build_orthogonalizer'
185
186 INTEGER :: acol, arow, handle, i, iatom, j, k, n
187 LOGICAL :: found
188 REAL(dp) :: v, w
189 REAL(dp), DIMENSION(:), POINTER :: evals
190 REAL(dp), DIMENSION(:, :), POINTER :: a, block_n, block_n_inv, block_s
191 TYPE(dbcsr_iterator_type) :: iter
192 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
193
194 CALL timeset(routinen, handle)
195
196 CALL get_qs_env(qs_env, matrix_s=matrix_s)
197
198 CALL dbcsr_create(pao%matrix_N, template=matrix_s(1)%matrix, name="PAO matrix_N")
199 CALL dbcsr_reserve_diag_blocks(pao%matrix_N)
200
201 CALL dbcsr_create(pao%matrix_N_inv, template=matrix_s(1)%matrix, name="PAO matrix_N_inv")
202 CALL dbcsr_reserve_diag_blocks(pao%matrix_N_inv)
203
204!$OMP PARALLEL DEFAULT(NONE) SHARED(pao,matrix_s) &
205!$OMP PRIVATE(iter,arow,acol,iatom,block_N,block_N_inv,block_S,found,N,A,evals,k,i,j,w,v)
206 CALL dbcsr_iterator_start(iter, pao%matrix_N)
207 DO WHILE (dbcsr_iterator_blocks_left(iter))
208 CALL dbcsr_iterator_next_block(iter, arow, acol, block_n)
209 iatom = arow; cpassert(arow == acol)
210
211 CALL dbcsr_get_block_p(matrix=pao%matrix_N_inv, row=iatom, col=iatom, block=block_n_inv, found=found)
212 cpassert(ASSOCIATED(block_n_inv))
213
214 CALL dbcsr_get_block_p(matrix=matrix_s(1)%matrix, row=iatom, col=iatom, block=block_s, found=found)
215 cpassert(ASSOCIATED(block_s))
216
217 n = SIZE(block_s, 1); cpassert(SIZE(block_s, 1) == SIZE(block_s, 2)) ! primary basis size
218 ALLOCATE (a(n, n), evals(n))
219
220 ! take square root of atomic overlap matrix
221 a = block_s
222 CALL diamat_all(a, evals) !afterwards A contains the eigenvectors
223 block_n = 0.0_dp
224 block_n_inv = 0.0_dp
225 DO k = 1, n
226 ! NOTE: To maintain a consistent notation with the Berghold paper,
227 ! the "_inv" is swapped: N^{-1}=sqrt(S); N=sqrt(S)^{-1}
228 w = 1.0_dp/sqrt(evals(k))
229 v = sqrt(evals(k))
230 DO i = 1, n
231 DO j = 1, n
232 block_n(i, j) = block_n(i, j) + w*a(i, k)*a(j, k)
233 block_n_inv(i, j) = block_n_inv(i, j) + v*a(i, k)*a(j, k)
234 END DO
235 END DO
236 END DO
237 DEALLOCATE (a, evals)
238 END DO
239 CALL dbcsr_iterator_stop(iter)
240!$OMP END PARALLEL
241
242 ! store a copies of N and N_inv that are distributed according to pao%diag_distribution
243 CALL dbcsr_create(pao%matrix_N_diag, &
244 name="PAO matrix_N_diag", &
245 dist=pao%diag_distribution, &
246 template=matrix_s(1)%matrix)
247 CALL dbcsr_reserve_diag_blocks(pao%matrix_N_diag)
248 CALL dbcsr_complete_redistribute(pao%matrix_N, pao%matrix_N_diag)
249 CALL dbcsr_create(pao%matrix_N_inv_diag, &
250 name="PAO matrix_N_inv_diag", &
251 dist=pao%diag_distribution, &
252 template=matrix_s(1)%matrix)
253 CALL dbcsr_reserve_diag_blocks(pao%matrix_N_inv_diag)
254 CALL dbcsr_complete_redistribute(pao%matrix_N_inv, pao%matrix_N_inv_diag)
255
256 CALL timestop(handle)
257 END SUBROUTINE pao_build_orthogonalizer
258
259! **************************************************************************************************
260!> \brief Build rectangular matrix to converert between primary and PAO basis.
261!> \param pao ...
262!> \param qs_env ...
263! **************************************************************************************************
264 SUBROUTINE pao_build_selector(pao, qs_env)
265 TYPE(pao_env_type), POINTER :: pao
266 TYPE(qs_environment_type), POINTER :: qs_env
267
268 CHARACTER(len=*), PARAMETER :: routinen = 'pao_build_selector'
269
270 INTEGER :: acol, arow, handle, i, iatom, ikind, m, &
271 natoms
272 INTEGER, DIMENSION(:), POINTER :: blk_sizes_aux, blk_sizes_pri
273 REAL(dp), DIMENSION(:, :), POINTER :: block_y
274 TYPE(dbcsr_iterator_type) :: iter
275 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
276 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
277 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
278
279 CALL timeset(routinen, handle)
280
281 CALL get_qs_env(qs_env, &
282 natom=natoms, &
283 matrix_s=matrix_s, &
284 qs_kind_set=qs_kind_set, &
285 particle_set=particle_set)
286
287 CALL dbcsr_get_info(matrix_s(1)%matrix, col_blk_size=blk_sizes_pri)
288
289 ALLOCATE (blk_sizes_aux(natoms))
290 DO iatom = 1, natoms
291 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
292 CALL get_qs_kind(qs_kind_set(ikind), pao_basis_size=m)
293 cpassert(m > 0)
294 IF (blk_sizes_pri(iatom) < m) THEN
295 cpabort("PAO basis size exceeds primary basis size.")
296 END IF
297 blk_sizes_aux(iatom) = m
298 END DO
299
300 CALL dbcsr_create(pao%matrix_Y, &
301 template=matrix_s(1)%matrix, &
302 matrix_type="N", &
303 row_blk_size=blk_sizes_pri, &
304 col_blk_size=blk_sizes_aux, &
305 name="PAO matrix_Y")
306 DEALLOCATE (blk_sizes_aux)
307
308 CALL dbcsr_reserve_diag_blocks(pao%matrix_Y)
309
310!$OMP PARALLEL DEFAULT(NONE) SHARED(pao) &
311!$OMP PRIVATE(iter,arow,acol,block_Y,i,M)
312 CALL dbcsr_iterator_start(iter, pao%matrix_Y)
313 DO WHILE (dbcsr_iterator_blocks_left(iter))
314 CALL dbcsr_iterator_next_block(iter, arow, acol, block_y)
315 m = SIZE(block_y, 2) ! size of pao basis
316 block_y = 0.0_dp
317 DO i = 1, m
318 block_y(i, i) = 1.0_dp
319 END DO
320 END DO
321 CALL dbcsr_iterator_stop(iter)
322!$OMP END PARALLEL
323
324 CALL timestop(handle)
325 END SUBROUTINE pao_build_selector
326
327! **************************************************************************************************
328!> \brief Creates new DBCSR distribution which spreads diagonal blocks evenly across ranks
329!> \param pao ...
330!> \param qs_env ...
331! **************************************************************************************************
332 SUBROUTINE pao_build_diag_distribution(pao, qs_env)
333 TYPE(pao_env_type), POINTER :: pao
334 TYPE(qs_environment_type), POINTER :: qs_env
335
336 CHARACTER(len=*), PARAMETER :: routinen = 'pao_build_diag_distribution'
337
338 INTEGER :: handle, iatom, natoms, pgrid_cols, &
339 pgrid_rows
340 INTEGER, DIMENSION(:), POINTER :: diag_col_dist, diag_row_dist
341 TYPE(dbcsr_distribution_type) :: main_dist
342 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
343
344 CALL timeset(routinen, handle)
345
346 CALL get_qs_env(qs_env, natom=natoms, matrix_s=matrix_s)
347
348 ! get processor grid from matrix_s
349 CALL dbcsr_get_info(matrix=matrix_s(1)%matrix, distribution=main_dist)
350 CALL dbcsr_distribution_get(main_dist, nprows=pgrid_rows, npcols=pgrid_cols)
351
352 ! create new mapping of matrix-grid to processor-grid
353 ALLOCATE (diag_row_dist(natoms), diag_col_dist(natoms))
354 DO iatom = 1, natoms
355 diag_row_dist(iatom) = mod(iatom - 1, pgrid_rows)
356 diag_col_dist(iatom) = mod((iatom - 1)/pgrid_rows, pgrid_cols)
357 END DO
358
359 ! instanciate distribution object
360 CALL dbcsr_distribution_new(pao%diag_distribution, template=main_dist, &
361 row_dist=diag_row_dist, col_dist=diag_col_dist)
362
363 DEALLOCATE (diag_row_dist, diag_col_dist)
364
365 CALL timestop(handle)
366 END SUBROUTINE pao_build_diag_distribution
367
368! **************************************************************************************************
369!> \brief Creates the matrix_X
370!> \param pao ...
371!> \param qs_env ...
372! **************************************************************************************************
373 SUBROUTINE pao_build_matrix_x(pao, qs_env)
374 TYPE(pao_env_type), POINTER :: pao
375 TYPE(qs_environment_type), POINTER :: qs_env
376
377 CHARACTER(len=*), PARAMETER :: routinen = 'pao_build_matrix_X'
378
379 INTEGER :: handle, iatom, ikind, natoms
380 INTEGER, DIMENSION(:), POINTER :: col_blk_size, row_blk_size
381 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
382
383 CALL timeset(routinen, handle)
384
385 CALL get_qs_env(qs_env, &
386 natom=natoms, &
387 particle_set=particle_set)
388
389 ! determine block-sizes of matrix_X
390 ALLOCATE (row_blk_size(natoms), col_blk_size(natoms))
391 col_blk_size = 1
392 DO iatom = 1, natoms
393 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
394 CALL pao_param_count(pao, qs_env, ikind, nparams=row_blk_size(iatom))
395 END DO
396
397 ! build actual matrix_X
398 CALL dbcsr_create(pao%matrix_X, &
399 name="PAO matrix_X", &
400 dist=pao%diag_distribution, &
401 matrix_type="N", &
402 row_blk_size=row_blk_size, &
403 col_blk_size=col_blk_size)
404 DEALLOCATE (row_blk_size, col_blk_size)
405
406 CALL dbcsr_reserve_diag_blocks(pao%matrix_X)
407 CALL dbcsr_set(pao%matrix_X, 0.0_dp)
408
409 CALL timestop(handle)
410 END SUBROUTINE pao_build_matrix_x
411
412! **************************************************************************************************
413!> \brief Creates the matrix_H0 which contains the core hamiltonian
414!> \param pao ...
415!> \param qs_env ...
416! **************************************************************************************************
417 SUBROUTINE pao_build_core_hamiltonian(pao, qs_env)
418 TYPE(pao_env_type), POINTER :: pao
419 TYPE(qs_environment_type), POINTER :: qs_env
420
421 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
422 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
423 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
424
425 CALL get_qs_env(qs_env, &
426 matrix_s=matrix_s, &
427 atomic_kind_set=atomic_kind_set, &
428 qs_kind_set=qs_kind_set)
429
430 ! allocate matrix_H0
431 CALL dbcsr_create(pao%matrix_H0, &
432 name="PAO matrix_H0", &
433 dist=pao%diag_distribution, &
434 template=matrix_s(1)%matrix)
435 CALL dbcsr_reserve_diag_blocks(pao%matrix_H0)
436
437 ! calculate initial atomic fock matrix H0
438 ! Can't use matrix_ks from ls_scf_qs_atomic_guess(), because it's not rotationally invariant.
439 ! getting H0 directly from the atomic code
440 CALL calculate_atomic_fock_matrix(pao%matrix_H0, &
441 atomic_kind_set, &
442 qs_kind_set, &
443 ounit=pao%iw)
444
445 END SUBROUTINE pao_build_core_hamiltonian
446
447! **************************************************************************************************
448!> \brief Test whether the PAO optimization has reached convergence
449!> \param pao ...
450!> \param ls_scf_env ...
451!> \param new_energy ...
452!> \param is_converged ...
453! **************************************************************************************************
454 SUBROUTINE pao_test_convergence(pao, ls_scf_env, new_energy, is_converged)
455 TYPE(pao_env_type), POINTER :: pao
456 TYPE(ls_scf_env_type) :: ls_scf_env
457 REAL(kind=dp), INTENT(IN) :: new_energy
458 LOGICAL, INTENT(OUT) :: is_converged
459
460 REAL(kind=dp) :: energy_diff, loop_eps, now, time_diff
461
462 ! calculate progress
463 energy_diff = new_energy - pao%energy_prev
464 pao%energy_prev = new_energy
465 now = m_walltime()
466 time_diff = now - pao%step_start_time
467 pao%step_start_time = now
468
469 ! convergence criterion
470 loop_eps = pao%norm_G/ls_scf_env%nelectron_total
471 is_converged = loop_eps < pao%eps_pao
472
473 IF (pao%istep > 1) THEN
474 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| energy improvement:", energy_diff
475 ! CPWARN_IF(energy_diff>0.0_dp, "PAO| energy increased")
476
477 ! print one-liner
478 IF (pao%iw > 0) WRITE (pao%iw, '(A,I6,11X,F20.9,1X,E10.3,1X,E10.3,1X,F9.3)') &
479 " PAO| step ", &
480 pao%istep, &
481 new_energy, &
482 loop_eps, &
483 pao%linesearch%step_size, & !prev step, which let to the current energy
484 time_diff
485 END IF
486 END SUBROUTINE pao_test_convergence
487
488! **************************************************************************************************
489!> \brief Calculate the pao energy
490!> \param pao ...
491!> \param qs_env ...
492!> \param ls_scf_env ...
493!> \param energy ...
494! **************************************************************************************************
495 SUBROUTINE pao_calc_energy(pao, qs_env, ls_scf_env, energy)
496 TYPE(pao_env_type), POINTER :: pao
497 TYPE(qs_environment_type), POINTER :: qs_env
498 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
499 REAL(kind=dp), INTENT(OUT) :: energy
500
501 CHARACTER(len=*), PARAMETER :: routinen = 'pao_calc_energy'
502
503 INTEGER :: handle, ispin
504 REAL(kind=dp) :: penalty, trace_ph
505
506 CALL timeset(routinen, handle)
507
508 ! calculate matrix U, which determines the pao basis
509 CALL pao_calc_ab(pao, qs_env, ls_scf_env, gradient=.false., penalty=penalty)
510
511 ! calculat S, S_inv, S_sqrt, and S_sqrt_inv in the new pao basis
512 CALL pao_rebuild_s(qs_env, ls_scf_env)
513
514 ! calculate the density matrix P in the pao basis
515 CALL pao_dm_trs4(qs_env, ls_scf_env)
516
517 ! calculate the energy from the trace(PH) in the pao basis
518 energy = 0.0_dp
519 DO ispin = 1, ls_scf_env%nspins
520 CALL dbcsr_dot(ls_scf_env%matrix_p(ispin), ls_scf_env%matrix_ks(ispin), trace_ph)
521 energy = energy + trace_ph
522 END DO
523
524 ! add penalty term
525 energy = energy + penalty
526
527 IF (pao%iw > 0) THEN
528 WRITE (pao%iw, *) ""
529 WRITE (pao%iw, *) "PAO| energy:", energy, "penalty:", penalty
530 END IF
531 CALL timestop(handle)
532 END SUBROUTINE pao_calc_energy
533
534! **************************************************************************************************
535!> \brief Ensure that the number of electrons is correct.
536!> \param ls_scf_env ...
537! **************************************************************************************************
538 SUBROUTINE pao_check_trace_ps(ls_scf_env)
539 TYPE(ls_scf_env_type) :: ls_scf_env
540
541 CHARACTER(len=*), PARAMETER :: routinen = 'pao_check_trace_PS'
542
543 INTEGER :: handle, ispin
544 REAL(kind=dp) :: tmp, trace_ps
545 TYPE(dbcsr_type) :: matrix_s_desym
546
547 CALL timeset(routinen, handle)
548 CALL dbcsr_create(matrix_s_desym, template=ls_scf_env%matrix_s, matrix_type="N")
549 CALL dbcsr_desymmetrize(ls_scf_env%matrix_s, matrix_s_desym)
550
551 trace_ps = 0.0_dp
552 DO ispin = 1, ls_scf_env%nspins
553 CALL dbcsr_dot(ls_scf_env%matrix_p(ispin), matrix_s_desym, tmp)
554 trace_ps = trace_ps + tmp
555 END DO
556
557 CALL dbcsr_release(matrix_s_desym)
558
559 IF (abs(ls_scf_env%nelectron_total - trace_ps) > 0.5) THEN
560 cpabort("Number of electrons wrong. Trace(PS) ="//cp_to_string(trace_ps))
561 END IF
562
563 CALL timestop(handle)
564 END SUBROUTINE pao_check_trace_ps
565
566! **************************************************************************************************
567!> \brief Read primary density matrix from file.
568!> \param pao ...
569!> \param qs_env ...
570! **************************************************************************************************
571 SUBROUTINE pao_read_preopt_dm(pao, qs_env)
572 TYPE(pao_env_type), POINTER :: pao
573 TYPE(qs_environment_type), POINTER :: qs_env
574
575 CHARACTER(len=*), PARAMETER :: routinen = 'pao_read_preopt_dm'
576
577 INTEGER :: handle, ispin
578 REAL(kind=dp) :: cs_pos
579 TYPE(dbcsr_distribution_type) :: dist
580 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, rho_ao
581 TYPE(dbcsr_type) :: matrix_tmp
582 TYPE(dft_control_type), POINTER :: dft_control
583 TYPE(qs_energy_type), POINTER :: energy
584 TYPE(qs_rho_type), POINTER :: rho
585
586 CALL timeset(routinen, handle)
587
588 CALL get_qs_env(qs_env, &
589 dft_control=dft_control, &
590 matrix_s=matrix_s, &
591 rho=rho, &
592 energy=energy)
593
594 CALL qs_rho_get(rho, rho_ao=rho_ao)
595
596 IF (dft_control%nspins /= 1) cpabort("open shell not yet implemented")
597
598 CALL dbcsr_get_info(matrix_s(1)%matrix, distribution=dist)
599
600 DO ispin = 1, dft_control%nspins
601 CALL dbcsr_binary_read(pao%preopt_dm_file, matrix_new=matrix_tmp, distribution=dist)
602 cs_pos = dbcsr_checksum(matrix_tmp, pos=.true.)
603 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| Read restart DM "// &
604 trim(pao%preopt_dm_file)//" with checksum: ", cs_pos
605 CALL dbcsr_copy(rho_ao(ispin)%matrix, matrix_tmp, keep_sparsity=.true.)
606 CALL dbcsr_release(matrix_tmp)
607 END DO
608
609 ! calculate corresponding ks matrix
610 CALL qs_rho_update_rho(rho, qs_env=qs_env)
611 CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.true.)
612 CALL qs_ks_update_qs_env(qs_env, calculate_forces=.false., &
613 just_energy=.false., print_active=.true.)
614 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| Quickstep energy from restart density:", energy%total
615
616 CALL timestop(handle)
617
618 END SUBROUTINE pao_read_preopt_dm
619
620! **************************************************************************************************
621!> \brief Rebuilds S, S_inv, S_sqrt, and S_sqrt_inv in the pao basis
622!> \param qs_env ...
623!> \param ls_scf_env ...
624! **************************************************************************************************
625 SUBROUTINE pao_rebuild_s(qs_env, ls_scf_env)
626 TYPE(qs_environment_type), POINTER :: qs_env
627 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
628
629 CHARACTER(len=*), PARAMETER :: routinen = 'pao_rebuild_S'
630
631 INTEGER :: handle
632 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
633
634 CALL timeset(routinen, handle)
635
636 CALL dbcsr_release(ls_scf_env%matrix_s_inv)
637 CALL dbcsr_release(ls_scf_env%matrix_s_sqrt)
638 CALL dbcsr_release(ls_scf_env%matrix_s_sqrt_inv)
639
640 CALL get_qs_env(qs_env, matrix_s=matrix_s)
641 CALL ls_scf_init_matrix_s(matrix_s(1)%matrix, ls_scf_env)
642
643 CALL timestop(handle)
644 END SUBROUTINE pao_rebuild_s
645
646! **************************************************************************************************
647!> \brief Calculate density matrix using TRS4 purification
648!> \param qs_env ...
649!> \param ls_scf_env ...
650! **************************************************************************************************
651 SUBROUTINE pao_dm_trs4(qs_env, ls_scf_env)
652 TYPE(qs_environment_type), POINTER :: qs_env
653 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
654
655 CHARACTER(len=*), PARAMETER :: routinen = 'pao_dm_trs4'
656
657 CHARACTER(LEN=default_path_length) :: project_name
658 INTEGER :: handle, ispin, nelectron_spin_real, nspin
659 LOGICAL :: converged
660 REAL(kind=dp) :: homo_spin, lumo_spin, mu_spin
661 TYPE(cp_logger_type), POINTER :: logger
662 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks
663
664 CALL timeset(routinen, handle)
665 logger => cp_get_default_logger()
666 project_name = logger%iter_info%project_name
667 nspin = ls_scf_env%nspins
668
669 CALL get_qs_env(qs_env, matrix_ks=matrix_ks)
670 DO ispin = 1, nspin
671 CALL matrix_qs_to_ls(ls_scf_env%matrix_ks(ispin), matrix_ks(ispin)%matrix, &
672 ls_scf_env%ls_mstruct, covariant=.true.)
673
674 nelectron_spin_real = ls_scf_env%nelectron_spin(ispin)
675 IF (ls_scf_env%nspins == 1) nelectron_spin_real = nelectron_spin_real/2
676 CALL density_matrix_trs4(ls_scf_env%matrix_p(ispin), ls_scf_env%matrix_ks(ispin), &
677 ls_scf_env%matrix_s_sqrt_inv, &
678 nelectron_spin_real, ls_scf_env%eps_filter, homo_spin, lumo_spin, mu_spin, &
679 dynamic_threshold=.false., converged=converged, &
680 max_iter_lanczos=ls_scf_env%max_iter_lanczos, &
681 eps_lanczos=ls_scf_env%eps_lanczos)
682 IF (.NOT. converged) cpabort("TRS4 did not converge")
683 END DO
684
685 IF (nspin == 1) CALL dbcsr_scale(ls_scf_env%matrix_p(1), 2.0_dp)
686
687 CALL timestop(handle)
688 END SUBROUTINE pao_dm_trs4
689
690! **************************************************************************************************
691!> \brief Debugging routine for checking the analytic gradient.
692!> \param pao ...
693!> \param qs_env ...
694!> \param ls_scf_env ...
695! **************************************************************************************************
696 SUBROUTINE pao_check_grad(pao, qs_env, ls_scf_env)
697 TYPE(pao_env_type), POINTER :: pao
698 TYPE(qs_environment_type), POINTER :: qs_env
699 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
700
701 CHARACTER(len=*), PARAMETER :: routinen = 'pao_check_grad'
702
703 INTEGER :: handle, i, iatom, j, natoms
704 INTEGER, DIMENSION(:), POINTER :: blk_sizes_col, blk_sizes_row
705 LOGICAL :: found
706 REAL(dp) :: delta, delta_max, eps, gij_num
707 REAL(dp), DIMENSION(:, :), POINTER :: block_g, block_x
708 TYPE(ls_mstruct_type), POINTER :: ls_mstruct
709 TYPE(mp_para_env_type), POINTER :: para_env
710
711 IF (pao%check_grad_tol < 0.0_dp) RETURN ! no checking
712
713 CALL timeset(routinen, handle)
714
715 ls_mstruct => ls_scf_env%ls_mstruct
716
717 CALL get_qs_env(qs_env, para_env=para_env, natom=natoms)
718
719 eps = pao%num_grad_eps
720 delta_max = 0.0_dp
721
722 CALL dbcsr_get_info(pao%matrix_X, col_blk_size=blk_sizes_col, row_blk_size=blk_sizes_row)
723
724 ! can not use an iterator here, because other DBCSR routines are called within loop.
725 DO iatom = 1, natoms
726 IF (pao%iw > 0) WRITE (pao%iw, *) 'PAO| checking gradient of atom ', iatom
727 CALL dbcsr_get_block_p(matrix=pao%matrix_X, row=iatom, col=iatom, block=block_x, found=found)
728
729 IF (ASSOCIATED(block_x)) THEN !only one node actually has the block
730 CALL dbcsr_get_block_p(matrix=pao%matrix_G, row=iatom, col=iatom, block=block_g, found=found)
731 cpassert(ASSOCIATED(block_g))
732 END IF
733
734 DO i = 1, blk_sizes_row(iatom)
735 DO j = 1, blk_sizes_col(iatom)
736 SELECT CASE (pao%num_grad_order)
737 CASE (2) ! calculate derivative to 2th order
738 gij_num = -eval_point(block_x, i, j, -eps, pao, ls_scf_env, qs_env)
739 gij_num = gij_num + eval_point(block_x, i, j, +eps, pao, ls_scf_env, qs_env)
740 gij_num = gij_num/(2.0_dp*eps)
741
742 CASE (4) ! calculate derivative to 4th order
743 gij_num = eval_point(block_x, i, j, -2_dp*eps, pao, ls_scf_env, qs_env)
744 gij_num = gij_num - 8_dp*eval_point(block_x, i, j, -1_dp*eps, pao, ls_scf_env, qs_env)
745 gij_num = gij_num + 8_dp*eval_point(block_x, i, j, +1_dp*eps, pao, ls_scf_env, qs_env)
746 gij_num = gij_num - eval_point(block_x, i, j, +2_dp*eps, pao, ls_scf_env, qs_env)
747 gij_num = gij_num/(12.0_dp*eps)
748
749 CASE (6) ! calculate derivative to 6th order
750 gij_num = -1_dp*eval_point(block_x, i, j, -3_dp*eps, pao, ls_scf_env, qs_env)
751 gij_num = gij_num + 9_dp*eval_point(block_x, i, j, -2_dp*eps, pao, ls_scf_env, qs_env)
752 gij_num = gij_num - 45_dp*eval_point(block_x, i, j, -1_dp*eps, pao, ls_scf_env, qs_env)
753 gij_num = gij_num + 45_dp*eval_point(block_x, i, j, +1_dp*eps, pao, ls_scf_env, qs_env)
754 gij_num = gij_num - 9_dp*eval_point(block_x, i, j, +2_dp*eps, pao, ls_scf_env, qs_env)
755 gij_num = gij_num + 1_dp*eval_point(block_x, i, j, +3_dp*eps, pao, ls_scf_env, qs_env)
756 gij_num = gij_num/(60.0_dp*eps)
757
758 CASE DEFAULT
759 cpabort("Unsupported numerical derivative order: "//cp_to_string(pao%num_grad_order))
760 END SELECT
761
762 IF (ASSOCIATED(block_x)) THEN
763 delta = abs(gij_num - block_g(i, j))
764 delta_max = max(delta_max, delta)
765 !WRITE (*,*) "gradient check", iatom, i, j, Gij_num, block_G(i,j), delta
766 END IF
767 END DO
768 END DO
769 END DO
770
771 CALL para_env%max(delta_max)
772 IF (pao%iw > 0) WRITE (pao%iw, *) 'PAO| checked gradient, max delta:', delta_max
773 IF (delta_max > pao%check_grad_tol) CALL cp_abort(__location__, &
774 "Analytic and numeric gradients differ too much:"//cp_to_string(delta_max))
775
776 CALL timestop(handle)
777 END SUBROUTINE pao_check_grad
778
779! **************************************************************************************************
780!> \brief Helper routine for pao_check_grad()
781!> \param block_X ...
782!> \param i ...
783!> \param j ...
784!> \param eps ...
785!> \param pao ...
786!> \param ls_scf_env ...
787!> \param qs_env ...
788!> \return ...
789! **************************************************************************************************
790 FUNCTION eval_point(block_X, i, j, eps, pao, ls_scf_env, qs_env) RESULT(energy)
791 REAL(dp), DIMENSION(:, :), POINTER :: block_x
792 INTEGER, INTENT(IN) :: i, j
793 REAL(dp), INTENT(IN) :: eps
794 TYPE(pao_env_type), POINTER :: pao
795 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
796 TYPE(qs_environment_type), POINTER :: qs_env
797 REAL(dp) :: energy
798
799 REAL(dp) :: old_xij
800
801 IF (ASSOCIATED(block_x)) THEN
802 old_xij = block_x(i, j) ! backup old block_X
803 block_x(i, j) = block_x(i, j) + eps ! add perturbation
804 END IF
805
806 ! calculate energy
807 CALL pao_calc_energy(pao, qs_env, ls_scf_env, energy)
808
809 ! restore old block_X
810 IF (ASSOCIATED(block_x)) THEN
811 block_x(i, j) = old_xij
812 END IF
813
814 END FUNCTION eval_point
815
816! **************************************************************************************************
817!> \brief Stores density matrix as initial guess for next SCF optimization.
818!> \param qs_env ...
819!> \param ls_scf_env ...
820! **************************************************************************************************
821 SUBROUTINE pao_store_p(qs_env, ls_scf_env)
822 TYPE(qs_environment_type), POINTER :: qs_env
823 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
824
825 CHARACTER(len=*), PARAMETER :: routinen = 'pao_store_P'
826
827 INTEGER :: handle, ispin, istore
828 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
829 TYPE(dft_control_type), POINTER :: dft_control
830 TYPE(ls_mstruct_type), POINTER :: ls_mstruct
831 TYPE(pao_env_type), POINTER :: pao
832
833 IF (ls_scf_env%scf_history%nstore == 0) RETURN
834 CALL timeset(routinen, handle)
835 ls_mstruct => ls_scf_env%ls_mstruct
836 pao => ls_scf_env%pao_env
837 CALL get_qs_env(qs_env, dft_control=dft_control, matrix_s=matrix_s)
838
839 ls_scf_env%scf_history%istore = ls_scf_env%scf_history%istore + 1
840 istore = mod(ls_scf_env%scf_history%istore - 1, ls_scf_env%scf_history%nstore) + 1
841 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| Storing density matrix for ASPC guess in slot:", istore
842
843 ! initialize storage
844 IF (ls_scf_env%scf_history%istore <= ls_scf_env%scf_history%nstore) THEN
845 DO ispin = 1, dft_control%nspins
846 CALL dbcsr_create(ls_scf_env%scf_history%matrix(ispin, istore), template=matrix_s(1)%matrix)
847 END DO
848 END IF
849
850 ! We are storing the density matrix in the non-orthonormal primary basis.
851 ! While the orthonormal basis would yield better extrapolations,
852 ! we simply can not afford to calculat S_sqrt in the primary basis.
853 DO ispin = 1, dft_control%nspins
854 ! transform into primary basis
855 CALL matrix_ls_to_qs(ls_scf_env%scf_history%matrix(ispin, istore), ls_scf_env%matrix_p(ispin), &
856 ls_scf_env%ls_mstruct, covariant=.false., keep_sparsity=.false.)
857 END DO
858
859 CALL timestop(handle)
860 END SUBROUTINE pao_store_p
861
862! **************************************************************************************************
863!> \brief Provide an initial guess for the density matrix
864!> \param pao ...
865!> \param qs_env ...
866!> \param ls_scf_env ...
867! **************************************************************************************************
868 SUBROUTINE pao_guess_initial_p(pao, qs_env, ls_scf_env)
869 TYPE(pao_env_type), POINTER :: pao
870 TYPE(qs_environment_type), POINTER :: qs_env
871 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
872
873 CHARACTER(len=*), PARAMETER :: routinen = 'pao_guess_initial_P'
874
875 INTEGER :: handle
876
877 CALL timeset(routinen, handle)
878
879 IF (ls_scf_env%scf_history%istore > 0) THEN
880 CALL pao_aspc_guess_p(pao, qs_env, ls_scf_env)
881 pao%need_initial_scf = .true.
882 ELSE
883 IF (len_trim(pao%preopt_dm_file) > 0) THEN
884 CALL pao_read_preopt_dm(pao, qs_env)
885 pao%need_initial_scf = .false.
886 pao%preopt_dm_file = "" ! load only for first MD step
887 ELSE
888 CALL ls_scf_qs_atomic_guess(qs_env, ls_scf_env, ls_scf_env%energy_init)
889 IF (pao%iw > 0) WRITE (pao%iw, '(A,F20.9)') &
890 " PAO| Energy from initial atomic guess:", ls_scf_env%energy_init
891 pao%need_initial_scf = .true.
892 END IF
893 END IF
894
895 CALL timestop(handle)
896
897 END SUBROUTINE pao_guess_initial_p
898
899! **************************************************************************************************
900!> \brief Run the Always Stable Predictor-Corrector to guess an initial density matrix
901!> \param pao ...
902!> \param qs_env ...
903!> \param ls_scf_env ...
904! **************************************************************************************************
905 SUBROUTINE pao_aspc_guess_p(pao, qs_env, ls_scf_env)
906 TYPE(pao_env_type), POINTER :: pao
907 TYPE(qs_environment_type), POINTER :: qs_env
908 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
909
910 CHARACTER(len=*), PARAMETER :: routinen = 'pao_aspc_guess_P'
911
912 INTEGER :: handle, iaspc, ispin, istore, naspc
913 REAL(dp) :: alpha
914 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
915 TYPE(dbcsr_type) :: matrix_p
916 TYPE(dft_control_type), POINTER :: dft_control
917 TYPE(ls_mstruct_type), POINTER :: ls_mstruct
918
919 CALL timeset(routinen, handle)
920 ls_mstruct => ls_scf_env%ls_mstruct
921 cpassert(ls_scf_env%scf_history%istore > 0)
922 CALL cite_reference(kolafa2004)
923 CALL cite_reference(kuhne2007)
924 CALL get_qs_env(qs_env, dft_control=dft_control, matrix_s=matrix_s)
925
926 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| Calculating initial guess with ASPC"
927
928 CALL dbcsr_create(matrix_p, template=matrix_s(1)%matrix)
929
930 naspc = min(ls_scf_env%scf_history%istore, ls_scf_env%scf_history%nstore)
931 DO ispin = 1, dft_control%nspins
932 ! actual extrapolation
933 CALL dbcsr_set(matrix_p, 0.0_dp)
934 DO iaspc = 1, naspc
935 alpha = (-1.0_dp)**(iaspc + 1)*real(iaspc, kind=dp)* &
936 binomial(2*naspc, naspc - iaspc)/binomial(2*naspc - 2, naspc - 1)
937 istore = mod(ls_scf_env%scf_history%istore - iaspc, ls_scf_env%scf_history%nstore) + 1
938 CALL dbcsr_add(matrix_p, ls_scf_env%scf_history%matrix(ispin, istore), 1.0_dp, alpha)
939 END DO
940
941 ! transform back from primary basis into pao basis
942 CALL matrix_qs_to_ls(ls_scf_env%matrix_p(ispin), matrix_p, ls_scf_env%ls_mstruct, covariant=.false.)
943 END DO
944
945 CALL dbcsr_release(matrix_p)
946
947 ! linear combination of P's is not idempotent. A bit of McWeeny is needed to ensure it is again
948 DO ispin = 1, dft_control%nspins
949 IF (dft_control%nspins == 1) CALL dbcsr_scale(ls_scf_env%matrix_p(ispin), 0.5_dp)
950 ! to ensure that noisy blocks do not build up during MD (in particular with curvy) filter that guess a bit more
951 CALL dbcsr_filter(ls_scf_env%matrix_p(ispin), ls_scf_env%eps_filter**(2.0_dp/3.0_dp))
952 ! we could go to the orthonomal basis, but it seems not worth the trouble
953 ! TODO : 10 iterations is a conservative upper bound, figure out when it fails
954 CALL purify_mcweeny(ls_scf_env%matrix_p(ispin:ispin), ls_scf_env%matrix_s, ls_scf_env%eps_filter, 10)
955 IF (dft_control%nspins == 1) CALL dbcsr_scale(ls_scf_env%matrix_p(ispin), 2.0_dp)
956 END DO
957
958 CALL pao_check_trace_ps(ls_scf_env) ! sanity check
959
960 ! compute corresponding energy and ks matrix
961 CALL ls_scf_dm_to_ks(qs_env, ls_scf_env, ls_scf_env%energy_init, iscf=0)
962
963 CALL timestop(handle)
964 END SUBROUTINE pao_aspc_guess_p
965
966! **************************************************************************************************
967!> \brief Calculate the forces contributed by PAO
968!> \param qs_env ...
969!> \param ls_scf_env ...
970! **************************************************************************************************
971 SUBROUTINE pao_add_forces(qs_env, ls_scf_env)
972 TYPE(qs_environment_type), POINTER :: qs_env
973 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
974
975 CHARACTER(len=*), PARAMETER :: routinen = 'pao_add_forces'
976
977 INTEGER :: handle, iatom, natoms
978 REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: forces
979 TYPE(mp_para_env_type), POINTER :: para_env
980 TYPE(pao_env_type), POINTER :: pao
981 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
982
983 CALL timeset(routinen, handle)
984 pao => ls_scf_env%pao_env
985
986 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| Adding forces."
987
988 IF (pao%max_pao /= 0) THEN
989 IF (pao%penalty_strength /= 0.0_dp) THEN
990 cpabort("PAO forces require PENALTY_STRENGTH or MAX_PAO set to zero")
991 END IF
992 IF (pao%linpot_regu_strength /= 0.0_dp) THEN
993 cpabort("PAO forces require LINPOT_REGULARIZATION_STRENGTH or MAX_PAO set to zero")
994 END IF
995 IF (pao%regularization /= 0.0_dp) THEN
996 cpabort("PAO forces require REGULARIZATION or MAX_PAO set to zero")
997 END IF
998 END IF
999
1000 CALL get_qs_env(qs_env, &
1001 para_env=para_env, &
1002 particle_set=particle_set, &
1003 natom=natoms)
1004
1005 ALLOCATE (forces(natoms, 3))
1006 CALL pao_calc_ab(pao, qs_env, ls_scf_env, gradient=.true., forces=forces) ! without penalty terms
1007
1008 IF (SIZE(pao%ml_training_set) > 0) THEN
1009 CALL pao_ml_forces(pao, qs_env, pao%matrix_G, forces)
1010 END IF
1011
1012 IF (ALLOCATED(pao%models)) THEN
1013 CALL pao_model_forces(pao, qs_env, pao%matrix_G, forces)
1014 END IF
1015
1016 CALL para_env%sum(forces)
1017 DO iatom = 1, natoms
1018 particle_set(iatom)%f = particle_set(iatom)%f + forces(iatom, :)
1019 END DO
1020
1021 DEALLOCATE (forces)
1022
1023 CALL timestop(handle)
1024
1025 END SUBROUTINE pao_add_forces
1026
1027END MODULE pao_methods
All kind of helpful little routines.
Definition ao_util.F:14
real(kind=dp) function, public exp_radius(l, alpha, threshold, prefactor, epsabs, epsrel, rlow)
The radius of a primitive Gaussian function for a given threshold is calculated. g(r) = prefactor*r**...
Definition ao_util.F:96
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.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public kuhne2007
integer, save, public kolafa2004
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_distribution_new(dist, template, group, pgrid, row_dist, col_dist, reuse_arrays)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
subroutine, public dbcsr_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_filter(matrix, eps)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_complete_redistribute(matrix, redist)
...
subroutine, public dbcsr_binary_read(filepath, distribution, matrix_new)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_distribution_get(dist, row_dist, col_dist, nrows, ncols, has_threads, group, mynode, numnodes, nprows, npcols, myprow, mypcol, pgrid, subgroups_defined, prow_group, pcol_group)
...
real(kind=dp) function, public dbcsr_checksum(matrix, pos)
Calculates the checksum of a DBCSR matrix.
subroutine, public dbcsr_dot(matrix_a, matrix_b, trace)
Computes the dot product of two matrices, also known as the trace of their matrix product.
subroutine, public dbcsr_reserve_diag_blocks(matrix)
Reserves all diagonal blocks.
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
lower level routines for linear scaling SCF
subroutine, public density_matrix_trs4(matrix_p, matrix_ks, matrix_s_sqrt_inv, nelectron, threshold, e_homo, e_lumo, e_mu, dynamic_threshold, matrix_ks_deviation, max_iter_lanczos, eps_lanczos, converged, iounit)
compute the density matrix using a trace-resetting algorithm
subroutine, public ls_scf_init_matrix_s(matrix_s, ls_scf_env)
initialize S matrix related properties (sqrt, inverse...) Might be factored-out since this seems comm...
Routines for a linear scaling quickstep SCF run based on the density matrix, with a focus on the inte...
subroutine, public ls_scf_qs_atomic_guess(qs_env, ls_scf_env, energy, nonscf)
get an atomic initial guess
subroutine, public matrix_ls_to_qs(matrix_qs, matrix_ls, ls_mstruct, covariant, keep_sparsity)
second link to QS, copy a LS matrix to QS matrix used to isolate QS style matrices from LS style will...
subroutine, public ls_scf_dm_to_ks(qs_env, ls_scf_env, energy_new, iscf)
use the density matrix in ls_scf_env to compute the new energy and KS matrix
subroutine, public matrix_qs_to_ls(matrix_ls, matrix_qs, ls_mstruct, covariant)
first link to QS, copy a QS matrix to LS matrix used to isolate QS style matrices from LS style will ...
Types needed for a linear scaling quickstep SCF run based on the density matrix.
Routines useful for iterative matrix calculations.
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_path_length
Definition kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:141
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
elemental real(kind=dp) function, public binomial(n, k)
The binomial coefficient n over k for 0 <= k <= n is calculated, otherwise zero is returned.
Definition mathlib.F:214
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...
Definition mathlib.F:381
Interface to the message passing library MPI.
Methods used by pao_main.F.
Definition pao_methods.F:12
subroutine, public pao_build_orthogonalizer(pao, qs_env)
Constructs matrix_N and its inverse.
subroutine, public pao_build_core_hamiltonian(pao, qs_env)
Creates the matrix_H0 which contains the core hamiltonian.
subroutine, public pao_guess_initial_p(pao, qs_env, ls_scf_env)
Provide an initial guess for the density matrix.
subroutine, public pao_test_convergence(pao, ls_scf_env, new_energy, is_converged)
Test whether the PAO optimization has reached convergence.
subroutine, public pao_add_forces(qs_env, ls_scf_env)
Calculate the forces contributed by PAO.
subroutine, public pao_check_trace_ps(ls_scf_env)
Ensure that the number of electrons is correct.
subroutine, public pao_init_kinds(pao, qs_env)
Initialize qs kinds.
Definition pao_methods.F:97
subroutine, public pao_build_matrix_x(pao, qs_env)
Creates the matrix_X.
subroutine, public pao_check_grad(pao, qs_env, ls_scf_env)
Debugging routine for checking the analytic gradient.
subroutine, public pao_print_atom_info(pao)
Prints a one line summary for each atom.
subroutine, public pao_store_p(qs_env, ls_scf_env)
Stores density matrix as initial guess for next SCF optimization.
subroutine, public pao_build_selector(pao, qs_env)
Build rectangular matrix to converert between primary and PAO basis.
subroutine, public pao_calc_energy(pao, qs_env, ls_scf_env, energy)
Calculate the pao energy.
subroutine, public pao_build_diag_distribution(pao, qs_env)
Creates new DBCSR distribution which spreads diagonal blocks evenly across ranks.
Main module for PAO Machine Learning.
Definition pao_ml.F:12
subroutine, public pao_ml_forces(pao, qs_env, matrix_g, forces)
Calculate forces contributed by machine learning.
Definition pao_ml.F:631
Module for equivariant PAO-ML based on PyTorch.
Definition pao_model.F:12
subroutine, public pao_model_forces(pao, qs_env, matrix_g, forces)
Calculate forces contributed by machine learning.
Definition pao_model.F:187
subroutine, public pao_model_load(pao, qs_env, ikind, pao_model_file, model)
Loads a PAO-ML model.
Definition pao_model.F:65
Front-End for any PAO parametrization.
Definition pao_param.F:12
subroutine, public pao_calc_ab(pao, qs_env, ls_scf_env, gradient, penalty, forces)
Takes current matrix_X and calculates the matrices A and B.
Definition pao_param.F:70
subroutine, public pao_param_count(pao, qs_env, ikind, nparams)
Returns the number of parameters for given atomic kind.
Definition pao_param.F:173
Factory routines for potentials used e.g. by pao_param_exp and pao_ml.
Types used by the PAO machinery.
Definition pao_types.F:12
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, 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.
Routines to somehow generate an initial guess.
subroutine, public calculate_atomic_fock_matrix(matrix_f, atomic_kind_set, qs_kind_set, ounit)
returns a block diagonal fock matrix.
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, 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, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
subroutine, public set_qs_kind(qs_kind, paw_atom, ghost, floating, hard_radius, hard0_radius, covalent_radius, vdw_radius, lmax_rho0, zeff, no_optimize, dispersion, u_minus_j, reltmat, dftb_parameter, xtb_parameter, elec_conf, pao_basis_size)
Set the components of an atomic kind data set.
routines that build the Kohn-Sham matrix (i.e calculate the coulomb and xc parts
subroutine, public qs_ks_update_qs_env(qs_env, calculate_forces, just_energy, print_active)
updates the Kohn Sham matrix of the given qs_env (facility method)
subroutine, public qs_ks_did_change(ks_env, s_mstruct_changed, rho_changed, potential_changed, full_reset)
tells that some of the things relevant to the ks calculation did change. has to be called when change...
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_update_rho(rho_struct, qs_env, rho_xc_external, local_rho_set, task_list_external, task_list_external_soft, pw_env_external, para_env_external)
updates rho_r and rho_g to the rhorho_ao. if use_kinetic_energy_density also computes tau_r and tau_g...
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
Provides all information about an atomic kind.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
Holds information about a PAO descriptor.
Holds information about a PAO potential.
Provides all information about a quickstep kind.
keeps the density in various representations, keeping track of which ones are valid.