(git:123285f)
Loading...
Searching...
No Matches
qs_cneo_utils.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 Utility functions for CNEO-DFT
10!> (see J. Chem. Theory Comput. 2025, 21, 16, 7865–7877)
11!> \par History
12!> 08.2025 created [zc62]
13!> \author Zehua Chen
14! **************************************************************************************************
16 USE ao_util, ONLY: trace_r_axb
19 USE kinds, ONLY: dp
23#include "./base/base_uses.f90"
24
25 IMPLICIT NONE
26
27 PRIVATE
28
29 ! *** Global parameters ***
30 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_cneo_utils'
31
32 ! *** Public subroutines ***
35
36CONTAINS
37
38! **************************************************************************************************
39!> \brief Mostly copied from qs_harmonics_atom::create_harmonics_atom
40!> \param harmonics ...
41!> \param my_CG ...
42!> \param llmax ...
43!> \param maxs ...
44!> \param max_s_harm ...
45! **************************************************************************************************
46 SUBROUTINE create_harmonics_atom_cneo(harmonics, my_CG, llmax, maxs, max_s_harm)
47
48 TYPE(harmonics_atom_type), POINTER :: harmonics
49 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: my_cg
50 INTEGER, INTENT(IN) :: llmax, maxs, max_s_harm
51
52 INTEGER :: i, is
53
54 cpassert(ASSOCIATED(harmonics))
55
56 harmonics%max_s_harm = max_s_harm
57 harmonics%llmax = llmax
58
59 NULLIFY (harmonics%my_CG, harmonics%my_CG_dxyz, harmonics%my_CG_dxyz_asym)
60 CALL reallocate(harmonics%my_CG, 1, maxs, 1, maxs, 1, max_s_harm)
61
62 DO i = 1, max_s_harm
63 DO is = 1, maxs
64 harmonics%my_CG(1:maxs, is, i) = my_cg(1:maxs, is, i)
65 END DO
66 END DO
67
68 END SUBROUTINE create_harmonics_atom_cneo
69
70! **************************************************************************************************
71!> \brief Mostly copied from qs_harmonics_atom::get_maxl_CG
72!> \param harmonics ...
73!> \param orb_basis ...
74!> \param llmax ...
75!> \param max_s_harm ...
76! **************************************************************************************************
77 SUBROUTINE get_maxl_cg_cneo(harmonics, orb_basis, llmax, max_s_harm)
78
79 TYPE(harmonics_atom_type), POINTER :: harmonics
80 TYPE(gto_basis_set_type), POINTER :: orb_basis
81 INTEGER, INTENT(IN) :: llmax, max_s_harm
82
83 INTEGER :: is1, is2, itmp, max_iso_not0, nset
84 INTEGER, DIMENSION(:), POINTER :: lmax, lmin
85
86 cpassert(ASSOCIATED(harmonics))
87
88 CALL get_gto_basis_set(gto_basis_set=orb_basis, lmax=lmax, lmin=lmin, nset=nset)
89
90 ! *** Assign indices for the non null CG coefficients ***
91 max_iso_not0 = 0
92 DO is1 = 1, nset
93 DO is2 = 1, nset
94 CALL get_none0_cg_list(harmonics%my_CG, &
95 lmin(is1), lmax(is1), lmin(is2), lmax(is2), &
96 max_s_harm, llmax, max_iso_not0=itmp)
97 max_iso_not0 = max(max_iso_not0, itmp)
98 END DO ! is2
99 END DO ! is1
100 harmonics%max_iso_not0 = max_iso_not0
101
102 END SUBROUTINE get_maxl_cg_cneo
103
104! **************************************************************************************************
105!> \brief Mostly copied from atom_utils::atom_solve
106!> \param hmat ...
107!> \param f ...
108!> \param umat ...
109!> \param orb ...
110!> \param ener ...
111!> \param pmat ...
112!> \param r ...
113!> \param dist ...
114!> \param nb ...
115!> \param nv ...
116! **************************************************************************************************
117 SUBROUTINE atom_solve_cneo(hmat, f, umat, orb, ener, pmat, r, dist, nb, nv)
118
119 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: hmat
120 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: f
121 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: umat
122 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: orb
123 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: ener
124 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: pmat
125 REAL(kind=dp), DIMENSION(3), INTENT(INOUT) :: r
126 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: dist
127 INTEGER, INTENT(IN) :: nb, nv
128
129 INTEGER :: info, lwork, m, n
130 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: w, work
131 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: a, b, h_fx
132
133 cpassert(nb >= nv)
134
135 orb = 0._dp
136 n = nb
137 m = nv
138 IF (n > 0 .AND. m > 0) THEN
139 lwork = max(n*n, n + 100)
140 ALLOCATE (a(m, m), b(n, m), w(m), work(lwork))
141 IF (dot_product(f, f) /= 0.0_dp) THEN
142 ALLOCATE (h_fx(n, n))
143 h_fx(1:n, 1:n) = hmat(1:n, 1:n) + f(1)*dist(1:n, 1:n, 1) + &
144 f(2)*dist(1:n, 1:n, 2) + f(3)*dist(1:n, 1:n, 3)
145 CALL dgemm("N", "N", n, m, n, 1.0_dp, h_fx, n, umat, n, 0.0_dp, b, n)
146 DEALLOCATE (h_fx)
147 ELSE
148 CALL dgemm("N", "N", n, m, n, 1.0_dp, hmat, n, umat, n, 0.0_dp, b, n)
149 END IF
150 CALL dgemm("T", "N", m, m, n, 1.0_dp, umat, n, b, n, 0.0_dp, a, m)
151 CALL dsyev("V", "U", m, a, m, w, work, lwork, info)
152 CALL dgemm("N", "N", n, m, m, 1.0_dp, umat, n, a, m, 0.0_dp, b, n)
153
154 m = min(m, SIZE(orb, 2))
155 orb(1:n, 1:m) = b(1:n, 1:m)
156 ener(1:m) = w(1:m)
157
158 DEALLOCATE (a, b, w, work)
159
160 ! calculate the density matrix using the orbital with the lowest orbital energy
161 pmat = 0.0_dp
162 CALL dger(n, n, 1.0_dp, orb(:, 1), 1, orb(:, 1), 1, pmat, n)
163 ! calculate the expectation position (basis center as the origin)
164 r = [trace_r_axb(dist(1:n, 1:n, 1), n, pmat, n, n, n), &
165 trace_r_axb(dist(1:n, 1:n, 2), n, pmat, n, n, n), &
166 trace_r_axb(dist(1:n, 1:n, 3), n, pmat, n, n, n)]
167 END IF
168
169 END SUBROUTINE atom_solve_cneo
170
171! **************************************************************************************************
172!> \brief Mostly copied from qs_oce_methods::prj_gather
173!> \param ain ...
174!> \param aout ...
175!> \param nbas ...
176!> \param n2oindex ...
177! **************************************************************************************************
178 SUBROUTINE cneo_gather(ain, aout, nbas, n2oindex)
179
180 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: ain
181 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: aout
182 INTEGER, INTENT(IN) :: nbas
183 INTEGER, DIMENSION(:), POINTER :: n2oindex
184
185 INTEGER :: i, ip, j, jp
186
187 DO i = 1, nbas
188 ip = n2oindex(i)
189 DO j = 1, nbas
190 jp = n2oindex(j)
191 aout(j, i) = ain(jp, ip)
192 END DO
193 END DO
194
195 END SUBROUTINE cneo_gather
196
197! **************************************************************************************************
198!> \brief Mostly copied from qs_oce_methods::prj_scatter
199!> \param ain ...
200!> \param aout ...
201!> \param nbas ...
202!> \param n2oindex ...
203! **************************************************************************************************
204 SUBROUTINE cneo_scatter(ain, aout, nbas, n2oindex)
205
206 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: ain
207 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: aout
208 INTEGER, INTENT(IN) :: nbas
209 INTEGER, DIMENSION(:), POINTER :: n2oindex
210
211 INTEGER :: i, ip, j, jp
212
213 DO i = 1, nbas
214 ip = n2oindex(i)
215 DO j = 1, nbas
216 jp = n2oindex(j)
217 aout(jp, ip) = aout(jp, ip) + ain(j, i)
218 END DO
219 END DO
220
221 END SUBROUTINE cneo_scatter
222
223END MODULE qs_cneo_utils
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
All kind of helpful little routines.
Definition ao_util.F:14
pure real(dp) function, public trace_r_axb(a, lda, b, ldb, m, n)
...
Definition ao_util.F:330
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum, ccon)
...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Utility routines for the memory handling.
Utility functions for CNEO-DFT (see J. Chem. Theory Comput. 2025, 21, 16, 7865–7877).
subroutine, public get_maxl_cg_cneo(harmonics, orb_basis, llmax, max_s_harm)
Mostly copied from qs_harmonics_atom::get_maxl_CG.
subroutine, public cneo_scatter(ain, aout, nbas, n2oindex)
Mostly copied from qs_oce_methods::prj_scatter.
subroutine, public atom_solve_cneo(hmat, f, umat, orb, ener, pmat, r, dist, nb, nv)
Mostly copied from atom_utils::atom_solve.
subroutine, public cneo_gather(ain, aout, nbas, n2oindex)
Mostly copied from qs_oce_methods::prj_gather.
subroutine, public create_harmonics_atom_cneo(harmonics, my_cg, llmax, maxs, max_s_harm)
Mostly copied from qs_harmonics_atom::create_harmonics_atom.