LIBINT 2.7.2
sto3g_atomic_density.h
1/*
2 * Copyright (C) 2004-2021 Edward F. Valeev
3 *
4 * This file is part of Libint.
5 *
6 * Libint is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Libint is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with Libint. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#ifndef INCLUDE_LIBINT2_CHEMISTRY_STO3GATOMICDENSITY_H_
22#define INCLUDE_LIBINT2_CHEMISTRY_STO3GATOMICDENSITY_H_
23
24#include <algorithm>
25#include <vector>
26
27namespace libint2 {
28
29namespace detail {
30
39template <typename Real>
40void subshell_occvec(Real*& occvec, size_t size, size_t& ne) {
41 const auto ne_alloc = (ne > 2 * size) ? 2 * size : ne;
42 ne -= ne_alloc;
43 // # of electrons / orbital compute as precisely as possible
44 const double ne_per_orb = (ne_alloc % size == 0)
45 ? static_cast<Real>(ne_alloc / size)
46 : (static_cast<Real>(ne_alloc)) / size;
47 for (size_t f = 0; f != size; ++f) occvec[f] = ne_per_orb;
48 occvec += size;
49}
50
51} // namespace detail
52
56inline size_t sto3g_num_ao(size_t Z) {
57 size_t nao;
58 if (Z == 1 || Z == 2) // H, He
59 nao = 1;
60 else if (Z <= 10) // Li - Ne
61 nao = 5; // 2p is included even for Li and Be
62 else if (Z <= 18) // Na - Ar
63 nao = 9; // 3p is included even for Na and Mg
64 else if (Z <= 20) // K, Ca
65 nao = 13; // 4p is included
66 else if (Z <= 36) // Sc - Kr
67 nao = 18;
68 else if (Z <= 38) // Rb, Sr
69 nao = 22; // 5p is included
70 else if (Z <= 53) // Y - I
71 nao = 27;
72 else
73 throw "STO-3G basis is not defined for elements with Z > 53";
74 return nao;
75}
76
83template <typename Real = double>
84const std::vector<Real>& sto3g_ao_occupation_vector(size_t Z) {
85 static std::vector<Real> occvec(27, 0.0);
86
88
89 occvec.resize(sto3g_num_ao(Z));
90 auto* occs_ptr = &occvec[0];
91 auto& occs = occs_ptr;
92
93 size_t num_of_electrons = Z; // # of electrons to allocate
94
95 // neutral atom electronic configurations from NIST:
96 // http://www.nist.gov/pml/data/images/illo_for_2014_PT_1.PNG
97 subshell_occvec(occs, 1, num_of_electrons); // 1s
98 if (Z > 2) { // Li+
99 subshell_occvec(occs, 1, num_of_electrons); // 2s
100 subshell_occvec(occs, 3, num_of_electrons); // 2p
101 }
102 if (Z > 10) { // Na+
103 subshell_occvec(occs, 1, num_of_electrons); // 3s
104 subshell_occvec(occs, 3, num_of_electrons); // 3p
105 }
106 if (18 < Z && Z <= 36) { // K .. Kr
107 // NB 4s is singly occupied in K, Cr, and Cu
108 size_t num_of_4s_electrons = (Z == 19 || Z == 24 || Z == 29) ? 1 : 2;
109 num_of_electrons -= num_of_4s_electrons;
110 subshell_occvec(occs, 1, num_of_4s_electrons); // 4s
111
112 size_t num_of_4p_electrons =
113 std::min(static_cast<decltype(Z)>(6), (Z > 30) ? Z - 30 : 0);
114 num_of_electrons -= num_of_4p_electrons;
115 subshell_occvec(occs, 3, num_of_4p_electrons); // 4p
116
117 subshell_occvec(occs, 5, num_of_electrons); // 3d
118 }
119 if (36 < Z && Z <= 53) { // Rb .. I
120 // 3d4s4p are fully occupied ...
121 subshell_occvec(occs, 1, num_of_electrons); // 4s
122 subshell_occvec(occs, 3, num_of_electrons); // 4p
123
124 // NB 5s is singly occupied in Rb, Nb, Mo, Ru, Rh, and Ag
125 size_t num_of_5s_electrons =
126 (Z == 37 || Z == 41 || Z == 42 || Z == 44 || Z == 45 || Z == 47) ? 1
127 : 2;
128 num_of_electrons -= num_of_5s_electrons;
129 subshell_occvec(occs, 1, num_of_5s_electrons); // 5s
130
131 size_t num_of_5p_electrons =
132 std::min(static_cast<decltype(Z)>(6), (Z > 48) ? Z - 48 : 0);
133 num_of_electrons -= num_of_5p_electrons;
134 subshell_occvec(occs, 3, num_of_5p_electrons); // 5p
135
136 subshell_occvec(occs, 5, num_of_electrons); // 3d
137 subshell_occvec(occs, 5, num_of_electrons); // 4d
138 }
139
140 return occvec;
141}
142
143} // namespace libint2
144
145
146
147#endif // INCLUDE_LIBINT2_CHEMISTRY_STO3GATOMICDENSITY_H_
void subshell_occvec(Real *&occvec, size_t size, size_t &ne)
computes orbital occupation numbers for a subshell of size size created by smearing no more than ne e...
Definition: sto3g_atomic_density.h:40
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24
const std::vector< Real > & sto3g_ao_occupation_vector(size_t Z)
computes average orbital occupancies in the ground state of a neutral atoms
Definition: sto3g_atomic_density.h:84
size_t sto3g_num_ao(size_t Z)
Definition: sto3g_atomic_density.h:56