(git:374b731)
Loading...
Searching...
No Matches
s_square_methods.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Methods related to (\cal S)^2 (i.e. spin)
10!> \par History
11!> 03.2006 copied compute_s_square from qs_scf_post (Joost VandeVondele)
12!> 08.2021 revised (Matthias Krack, MK)
13!> \author Joost VandeVondele
14! **************************************************************************************************
16
23 USE cp_fm_types, ONLY: cp_fm_create,&
27 USE dbcsr_api, ONLY: dbcsr_p_type
30 USE kinds, ONLY: dp
33 USE qs_mo_types, ONLY: get_mo_set,&
36#include "./base/base_uses.f90"
37
38 IMPLICIT NONE
39
40 PRIVATE
41
42 ! Global parameters
43
44 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 's_square_methods'
45
47
48CONTAINS
49
50! **************************************************************************************************
51!> \brief Compute the expectation value <(\cal S)^2> of the single determinant defined by the
52!> spin up (alpha) and spin down (beta) orbitals
53!> \param mos [in] MO set with all MO information including the alpha and beta MO coefficients
54!> \param matrix_s [in] AO overlap matrix S (do not mix with the spin operator (\cal S))
55!> \param s_square [out] <(\cal S)^2> including potential spin contaminations
56!> \param s_square_ideal [out] Ideal value for <(\cal S)^2> without any spin contaminations
57!> \param mo_derivs [inout] If present, add the derivative of s_square wrt the MOs to mo_derivs
58!> \param strength [in] Strength for constraining or restraining (\cal S)^2
59!> \par History
60!> 07.2004 created (Joost VandeVondele)
61!> 08.2021 revised (Matthias Krack, MK)
62!> \note
63!> See Eqs. 2.271 and 2.272 in Modern Quantum Chemistry by A. Szabo and N. S. Ostlund
64! **************************************************************************************************
65 SUBROUTINE compute_s_square(mos, matrix_s, s_square, s_square_ideal, mo_derivs, strength)
66
67 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
68 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
69 REAL(kind=dp), INTENT(OUT) :: s_square, s_square_ideal
70 TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT), &
71 OPTIONAL :: mo_derivs
72 REAL(kind=dp), INTENT(IN), OPTIONAL :: strength
73
74 CHARACTER(len=*), PARAMETER :: routinen = 'compute_s_square'
75
76 INTEGER :: handle, i, j, nalpha, nao, nao_beta, &
77 nbeta, ncol_local, nmo_alpha, &
78 nmo_beta, nrow_local
79 LOGICAL :: has_uniform_occupation_alpha, &
80 has_uniform_occupation_beta
81 REAL(kind=dp) :: s2
82 REAL(kind=dp), CONTIGUOUS, DIMENSION(:, :), &
83 POINTER :: local_data
84 TYPE(cp_blacs_env_type), POINTER :: context
85 TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
86 TYPE(cp_fm_type) :: catscb, sca, scb
87 TYPE(cp_fm_type), POINTER :: c_alpha, c_beta
88 TYPE(mp_para_env_type), POINTER :: para_env
89
90 CALL timeset(routinen, handle)
91
92 NULLIFY (context)
93 NULLIFY (fm_struct_tmp)
94 NULLIFY (local_data)
95 NULLIFY (para_env)
96
97 SELECT CASE (SIZE(mos))
98 CASE (1)
99 ! Spin restricted case, i.e. nothing to do
100 s_square = 0.0_dp
101 s_square_ideal = 0.0_dp
102 ! Restraining or constraining (\cal S) does not make sense
103 cpassert(PRESENT(mo_derivs) .OR. PRESENT(strength))
104 CASE (2)
105 CALL get_mo_set(mo_set=mos(1), mo_coeff=c_alpha, homo=nalpha, nmo=nmo_alpha, nao=nao)
106 CALL get_mo_set(mo_set=mos(2), mo_coeff=c_beta, homo=nbeta, nmo=nmo_beta, nao=nao_beta)
107 cpassert(nao == nao_beta)
108 has_uniform_occupation_alpha = has_uniform_occupation(mo_set=mos(1), last_mo=nalpha)
109 has_uniform_occupation_beta = has_uniform_occupation(mo_set=mos(2), last_mo=nbeta)
110 ! This makes only sense if we have uniform occupations for the alpha and beta spin MOs while
111 ! ignoring potentially added MOs with zero occupation
112 IF (has_uniform_occupation_alpha .AND. has_uniform_occupation_beta) THEN
113 ! Eq. 2.272 in Modern Quantum Chemistry by A. Szabo and N. S. Ostlund
114 s_square_ideal = real((nalpha - nbeta)*(nalpha - nbeta + 2), kind=dp)/4.0_dp
115 ! Create overlap matrix
116 CALL cp_fm_get_info(c_alpha, para_env=para_env, context=context)
117 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=context, &
118 nrow_global=nalpha, ncol_global=nbeta)
119 ! Prepare C(alpha)^T*S*C(beta)
120 CALL cp_fm_create(catscb, fm_struct_tmp, name="C(alpha)^T*S*C(beta)")
121 CALL cp_fm_struct_release(fm_struct_tmp)
122 ! Create S*C(beta)
123 CALL cp_fm_get_info(c_beta, matrix_struct=fm_struct_tmp)
124 CALL cp_fm_create(scb, fm_struct_tmp, name="S*C(beta)")
125 ! Compute S*C(beta)
126 CALL cp_dbcsr_sm_fm_multiply(matrix_s(1)%matrix, c_beta, scb, nbeta)
127 ! Compute C(alpha)^T*S*C(beta)
128 CALL parallel_gemm('T', 'N', nalpha, nbeta, nao, 1.0_dp, c_alpha, scb, 0.0_dp, catscb)
129 ! Eq. 2.271 in Modern Quantum Chemistry by A. Szabo and N. S. Ostlund
130 CALL cp_fm_get_info(catscb, local_data=local_data, nrow_local=nrow_local, ncol_local=ncol_local)
131 s2 = 0.0_dp
132 DO j = 1, ncol_local
133 DO i = 1, nrow_local
134 s2 = s2 + local_data(i, j)**2
135 END DO
136 END DO
137 CALL para_env%sum(s2)
138 s_square = s_square_ideal + nbeta - s2
139 ! Only needed for constraining or restraining (\cal S)
140 IF (PRESENT(mo_derivs)) THEN
141 cpassert(SIZE(mo_derivs, 1) == 2)
142 ! This gets really wrong for fractional occupations
143 CALL get_mo_set(mo_set=mos(1), uniform_occupation=has_uniform_occupation_alpha)
144 cpassert(has_uniform_occupation_alpha)
145 CALL get_mo_set(mo_set=mos(2), uniform_occupation=has_uniform_occupation_beta)
146 cpassert(has_uniform_occupation_beta)
147 ! Add -strength*S*C(beta)*(C(alpha)^T*S*C(beta))^T to the alpha MO derivatives
148 CALL parallel_gemm('N', 'T', nao, nalpha, nbeta, -strength, scb, catscb, 1.0_dp, mo_derivs(1))
149 ! Create S*C(alpha)
150 CALL cp_fm_get_info(c_alpha, matrix_struct=fm_struct_tmp)
151 CALL cp_fm_create(sca, fm_struct_tmp, name="S*C(alpha)")
152 ! Compute S*C(alpha)
153 CALL cp_dbcsr_sm_fm_multiply(matrix_s(1)%matrix, c_alpha, sca, nalpha)
154 ! Add -strength*S*C(alpha)*C(alpha)^T*S*C(beta) to the beta MO derivatives
155 CALL parallel_gemm('N', 'N', nao, nbeta, nalpha, -strength, sca, catscb, 1.0_dp, mo_derivs(2))
156 CALL cp_fm_release(sca)
157 END IF
158 CALL cp_fm_release(scb)
159 CALL cp_fm_release(catscb)
160 ELSE
161 IF (.NOT. has_uniform_occupation_alpha) THEN
162 cphint("The alpha orbitals (MOs) have a non-uniform occupation")
163 END IF
164 IF (.NOT. has_uniform_occupation_beta) THEN
165 cphint("The beta orbitals (MOs) have a non-uniform occupation")
166 END IF
167 cphint("Skipping S**2 calculation")
168 END IF
169 CASE DEFAULT
170 ! We should never get here
171 cpabort("Alpha, beta, what else ?")
172 END SELECT
173
174 CALL timestop(handle)
175
176 END SUBROUTINE compute_s_square
177
178! **************************************************************************************************
179!> \brief restrains/constrains the value of s2 in a calculation
180!> \param mos input
181!> \param matrix_s input
182!> \param mo_derivs inout if present, add the derivative of s_square wrt mos to mo_derivs
183!> \param energy ...
184!> \param s2_restraint_control ...
185!> \param just_energy ...
186!> \par History
187!> 07.2004 created [ Joost VandeVondele ]
188! **************************************************************************************************
189 SUBROUTINE s2_restraint(mos, matrix_s, mo_derivs, energy, &
190 s2_restraint_control, just_energy)
191
192 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
193 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
194 TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT) :: mo_derivs
195 REAL(kind=dp) :: energy
196 TYPE(s2_restraint_type), POINTER :: s2_restraint_control
197 LOGICAL :: just_energy
198
199 CHARACTER(len=*), PARAMETER :: routinen = 's2_restraint'
200
201 INTEGER :: handle
202 REAL(kind=dp) :: s_square, s_square_ideal
203
204 CALL timeset(routinen, handle)
205
206 SELECT CASE (s2_restraint_control%functional_form)
207 CASE (do_s2_constraint)
208 IF (just_energy) THEN
209 CALL compute_s_square(mos, matrix_s, s_square, s_square_ideal)
210 ELSE
211 CALL compute_s_square(mos, matrix_s, s_square, s_square_ideal, &
212 mo_derivs, s2_restraint_control%strength)
213 END IF
214 energy = s2_restraint_control%strength*(s_square - s2_restraint_control%target)
215 s2_restraint_control%s2_order_p = s_square
216 CASE (do_s2_restraint) ! not yet implemented
217 cpabort("")
218 CASE DEFAULT
219 cpabort("")
220 END SELECT
221
222 CALL timestop(handle)
223
224 END SUBROUTINE s2_restraint
225
226END MODULE s_square_methods
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_s2_restraint
integer, parameter, public do_s2_constraint
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
logical function, public has_uniform_occupation(mo_set, first_mo, last_mo, occupation, tolerance)
Check if the set of MOs in mo_set specifed by the MO index range [first_mo,last_mo] an integer occupa...
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Methods related to (\cal S)^2 (i.e. spin)
subroutine, public s2_restraint(mos, matrix_s, mo_derivs, energy, s2_restraint_control, just_energy)
restrains/constrains the value of s2 in a calculation
subroutine, public compute_s_square(mos, matrix_s, s_square, s_square_ideal, mo_derivs, strength)
Compute the expectation value <(\cal S)^2> of the single determinant defined by the spin up (alpha) a...
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
represent a full matrix
stores all the informations relevant to an mpi environment