28#include "./base/base_uses.f90"
35 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_cneo_utils'
52 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: my_cg
53 INTEGER,
INTENT(IN) :: lcleb, maxl, llmax
55 INTEGER :: il, iso, iso1, iso2, l1, l1l2, l2, lc1, &
56 lc2, lp, m1, m2, mm, mp
57 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: rga
62 ALLOCATE (rga(lcleb, 2))
72 IF (l1 + l2 > llmax)
THEN
79 IF (m1*m2 < 0 .OR. (m1*m2 == 0 .AND. (m1 < 0 .OR. m2 < 0)))
THEN
86 DO lp = mod(l1 + l2, 2), l1l2, 2
88 IF (abs(mp) <= lp)
THEN
90 iso =
nsoset(lp - 1) + lp + 1 + mp
92 iso =
nsoset(lp - 1) + lp + 1 - abs(mp)
94 my_cg(iso1, iso2, iso) = rga(il, 1)
96 IF (mp /= mm .AND. abs(mm) <= lp)
THEN
98 iso =
nsoset(lp - 1) + lp + 1 + mm
100 iso =
nsoset(lp - 1) + lp + 1 - abs(mm)
102 my_cg(iso1, iso2, iso) = rga(il, 2)
125 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: my_cg
126 INTEGER,
INTENT(IN) :: llmax, maxs, max_s_harm
130 cpassert(
ASSOCIATED(harmonics))
132 harmonics%max_s_harm = max_s_harm
133 harmonics%llmax = llmax
135 NULLIFY (harmonics%my_CG, harmonics%my_CG_dxyz, harmonics%my_CG_dxyz_asym)
136 CALL reallocate(harmonics%my_CG, 1, maxs, 1, maxs, 1, max_s_harm)
140 harmonics%my_CG(1:maxs, is, i) = my_cg(1:maxs, is, i)
157 INTEGER,
INTENT(IN) :: llmax, max_s_harm
159 INTEGER :: is1, is2, itmp, max_iso_not0, nset
160 INTEGER,
DIMENSION(:),
POINTER :: lmax, lmin
162 cpassert(
ASSOCIATED(harmonics))
171 lmin(is1), lmax(is1), lmin(is2), lmax(is2), &
172 max_s_harm, llmax, max_iso_not0=itmp)
173 max_iso_not0 = max(max_iso_not0, itmp)
176 harmonics%max_iso_not0 = max_iso_not0
195 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: hmat
196 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: f
197 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: umat
198 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: orb
199 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: ener
200 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: pmat
201 REAL(kind=
dp),
DIMENSION(3),
INTENT(INOUT) :: r
202 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: dist
203 INTEGER,
INTENT(IN) :: nb, nv
205 INTEGER :: info, lwork, m, n
206 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: w, work
207 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: a, b, h_fx
214 IF (n > 0 .AND. m > 0)
THEN
215 lwork = max(n*n, n + 100)
216 ALLOCATE (a(m, m), b(n, m), w(m), work(lwork))
217 IF (dot_product(f, f) /= 0.0_dp)
THEN
218 ALLOCATE (h_fx(n, n))
219 h_fx(1:n, 1:n) = hmat(1:n, 1:n) + f(1)*dist(1:n, 1:n, 1) + &
220 f(2)*dist(1:n, 1:n, 2) + f(3)*dist(1:n, 1:n, 3)
221 CALL dgemm(
"N",
"N", n, m, n, 1.0_dp, h_fx, n, umat, n, 0.0_dp, b, n)
224 CALL dgemm(
"N",
"N", n, m, n, 1.0_dp, hmat, n, umat, n, 0.0_dp, b, n)
226 CALL dgemm(
"T",
"N", m, m, n, 1.0_dp, umat, n, b, n, 0.0_dp, a, m)
227 CALL dsyev(
"V",
"U", m, a, m, w, work, lwork, info)
228 CALL dgemm(
"N",
"N", n, m, m, 1.0_dp, umat, n, a, m, 0.0_dp, b, n)
230 m = min(m,
SIZE(orb, 2))
231 orb(1:n, 1:m) = b(1:n, 1:m)
234 DEALLOCATE (a, b, w, work)
238 CALL dger(n, n, 1.0_dp, orb(:, 1), 1, orb(:, 1), 1, pmat, n)
240 r = (/
trace_r_axb(dist(1:n, 1:n, 1), n, pmat, n, n, n), &
241 trace_r_axb(dist(1:n, 1:n, 2), n, pmat, n, n, n), &
256 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: ain
257 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: aout
258 INTEGER,
INTENT(IN) :: nbas
259 INTEGER,
DIMENSION(:),
POINTER :: n2oindex
261 INTEGER :: i, ip, j, jp
267 aout(j, i) = ain(jp, ip)
282 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: ain
283 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: aout
284 INTEGER,
INTENT(IN) :: nbas
285 INTEGER,
DIMENSION(:),
POINTER :: n2oindex
287 INTEGER :: i, ip, j, jp
293 aout(jp, ip) = aout(jp, ip) + ain(j, i)
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.
pure real(dp) function, public trace_r_axb(a, lda, b, ldb, m, n)
...
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)
...
Defines the basic variable types.
integer, parameter, public dp
Utility routines for the memory handling.
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public nsoset
integer, dimension(:, :), allocatable, public indso
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 create_my_cg_cneo(my_cg, lcleb, maxl, llmax)
Mostly copied from qs_rho_atom_methods::init_rho_atom.
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.
Calculate spherical harmonics.
subroutine, public clebsch_gordon_init(l)
...
subroutine, public clebsch_gordon_deallocate()
...