(git:ed6f26b)
Loading...
Searching...
No Matches
qs_atomic_block.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routine to return block diagonal density matrix. Blocks correspond to the atomic densities
10!> \par History
11!> 2006.03 Moved here from qs_scf.F [Joost VandeVondele]
12!> 2022.05 split from qs_initial_guess.F to break circular dependency [Harald Forbert]
13! **************************************************************************************************
18 USE cp_dbcsr_api, ONLY: &
24 USE kinds, ONLY: dp
27#include "./base/base_uses.f90"
28
29 IMPLICIT NONE
30
31 PRIVATE
32
33 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_atomic_block'
34
36
37 TYPE atom_matrix_type
38 REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: mat => null()
39 END TYPE atom_matrix_type
40
41CONTAINS
42
43! **************************************************************************************************
44!> \brief returns a block diagonal density matrix. Blocks correspond to the atomic densities.
45!> \param pmatrix ...
46!> \param matrix_s ...
47!> \param atomic_kind_set ...
48!> \param qs_kind_set ...
49!> \param nspin ...
50!> \param nelectron_spin ...
51!> \param ounit ...
52!> \param para_env ...
53! **************************************************************************************************
54 SUBROUTINE calculate_atomic_block_dm(pmatrix, matrix_s, atomic_kind_set, &
55 qs_kind_set, nspin, nelectron_spin, ounit, para_env)
56 TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT) :: pmatrix
57 TYPE(dbcsr_type), INTENT(INOUT) :: matrix_s
58 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
59 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
60 INTEGER, INTENT(IN) :: nspin
61 INTEGER, DIMENSION(:), INTENT(IN) :: nelectron_spin
62 INTEGER, INTENT(IN) :: ounit
63 TYPE(mp_para_env_type) :: para_env
64
65 CHARACTER(LEN=*), PARAMETER :: routinen = 'calculate_atomic_block_dm'
66
67 INTEGER :: handle, icol, ikind, irow, ispin, nc, &
68 nkind, nocc(2)
69 INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of
70 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: nok
71 REAL(dp), DIMENSION(:, :), POINTER :: pdata
72 REAL(kind=dp) :: rds, rscale, trps1
73 TYPE(atom_matrix_type), ALLOCATABLE, DIMENSION(:) :: pmat
74 TYPE(atomic_kind_type), POINTER :: atomic_kind
75 TYPE(dbcsr_iterator_type) :: iter
76 TYPE(dbcsr_type), POINTER :: matrix_p
77 TYPE(qs_kind_type), POINTER :: qs_kind
78
79 CALL timeset(routinen, handle)
80
81 nkind = SIZE(atomic_kind_set)
82 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, kind_of=kind_of)
83 ALLOCATE (pmat(nkind))
84 ALLOCATE (nok(2, nkind))
85
86 ! precompute the atomic blocks corresponding to spherical atoms
87 DO ikind = 1, nkind
88 atomic_kind => atomic_kind_set(ikind)
89 qs_kind => qs_kind_set(ikind)
90 NULLIFY (pmat(ikind)%mat)
91 IF (ounit > 0) THEN
92 WRITE (unit=ounit, fmt="(/,T2,A)") &
93 "Guess for atomic kind: "//trim(atomic_kind%name)
94 END IF
95 CALL calculate_atomic_orbitals(atomic_kind, qs_kind, iunit=ounit, &
96 pmat=pmat(ikind)%mat, nocc=nocc)
97 nok(1:2, ikind) = nocc(1:2)
98 END DO
99
100 rscale = 1.0_dp
101 IF (nspin == 2) rscale = 0.5_dp
102
103 DO ispin = 1, nspin
104 IF ((ounit > 0) .AND. (nspin > 1)) THEN
105 WRITE (unit=ounit, fmt="(/,T2,A,I0)") "Spin ", ispin
106 END IF
107
108 matrix_p => pmatrix(ispin)%matrix
109 CALL dbcsr_set(matrix_p, 0.0_dp)
110
111 nocc(ispin) = 0
112 CALL dbcsr_iterator_start(iter, matrix_p)
113 DO WHILE (dbcsr_iterator_blocks_left(iter))
114 CALL dbcsr_iterator_next_block(iter, irow, icol, pdata)
115 ikind = kind_of(irow)
116 IF (icol .EQ. irow) THEN
117 IF (ispin == 1) THEN
118 pdata(:, :) = pmat(ikind)%mat(:, :, 1)*rscale + &
119 pmat(ikind)%mat(:, :, 2)*rscale
120 ELSE
121 pdata(:, :) = pmat(ikind)%mat(:, :, 1)*rscale - &
122 pmat(ikind)%mat(:, :, 2)*rscale
123 END IF
124 nocc(ispin) = nocc(ispin) + nok(ispin, ikind)
125 END IF
126 END DO
127 CALL dbcsr_iterator_stop(iter)
128
129 CALL dbcsr_dot(matrix_p, matrix_s, trps1)
130 rds = 0.0_dp
131 ! could be a ghost-atoms-only simulation
132 IF (nelectron_spin(ispin) > 0) THEN
133 rds = real(nelectron_spin(ispin), dp)/trps1
134 END IF
135 CALL dbcsr_scale(matrix_p, rds)
136
137 IF (ounit > 0) THEN
138 IF (nspin > 1) THEN
139 WRITE (unit=ounit, fmt="(T2,A,I1)") &
140 "Re-scaling the density matrix to get the right number of electrons for spin ", ispin
141 ELSE
142 WRITE (unit=ounit, fmt="(T2,A)") &
143 "Re-scaling the density matrix to get the right number of electrons"
144 END IF
145 WRITE (ounit, '(T19,A,T44,A,T67,A)') "# Electrons", "Trace(P)", "Scaling factor"
146 WRITE (ounit, '(T20,I10,T40,F12.3,T67,F14.3)') nelectron_spin(ispin), trps1, rds
147 END IF
148
149 IF (nspin > 1) THEN
150 CALL para_env%sum(nocc)
151 IF (nelectron_spin(ispin) > nocc(ispin)) THEN
152 rds = 0.99_dp
153 CALL dbcsr_scale(matrix_p, rds)
154 rds = (1.0_dp - rds)*nelectron_spin(ispin)
155 CALL dbcsr_get_info(matrix_p, nfullcols_total=nc)
156 rds = rds/real(nc, kind=dp)
157 CALL dbcsr_add_on_diag(matrix_p, rds)
158 IF (ounit > 0) THEN
159 WRITE (unit=ounit, fmt="(T4,A,/,T4,A,T59,F20.12)") &
160 "More MOs than initial guess orbitals detected", &
161 "Add constant to diagonal elements ", rds
162 END IF
163 END IF
164 END IF
165
166 END DO
167
168 DO ikind = 1, nkind
169 IF (ASSOCIATED(pmat(ikind)%mat)) THEN
170 DEALLOCATE (pmat(ikind)%mat)
171 END IF
172 END DO
173 DEALLOCATE (pmat)
174
175 DEALLOCATE (kind_of, nok)
176
177 CALL timestop(handle)
178
179 END SUBROUTINE calculate_atomic_block_dm
180
181END MODULE qs_atomic_block
calculate the orbitals for a given atomic kind type
subroutine, public calculate_atomic_orbitals(atomic_kind, qs_kind, agrid, iunit, pmat, fmat, density, wavefunction, wfninfo, confine, xc_section, nocc)
...
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
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_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_add_on_diag(matrix, alpha)
Adds the given scalar to the diagonal of the matrix. Reserves any missing diagonal blocks.
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.
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
Routine to return block diagonal density matrix. Blocks correspond to the atomic densities.
subroutine, public calculate_atomic_block_dm(pmatrix, matrix_s, atomic_kind_set, qs_kind_set, nspin, nelectron_spin, ounit, para_env)
returns a block diagonal density matrix. Blocks correspond to the atomic densities.
Define the quickstep kind type and their sub types.
Provides all information about an atomic kind.
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.