MADNESS 0.10.1
population.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program 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 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30*/
31
32/// \file population.h
33/// \brief atomic populations of occupied orbitals: Mulliken, Loewdin and intrinsic atomic orbitals (IAO)
34
35/// Everything here works on overlap matrices alone, so the same functions serve
36/// MRA orbitals (overlaps by quadrature) and Gaussian-basis orbitals (analytic
37/// overlaps). The inputs, for the occupied orbitals phi_i of one spin:
38/// - phi_i orthonormal, <phi_i|phi_j> = delta_ij, with occupations n_i
39/// - a basis chi_mu centred on the atoms; S = <chi|chi>, X = <chi|phi>
40/// - the atom each basis function sits on
41/// S and X must refer to the same functions chi (e.g. both from the same
42/// projection into MRA).
43
44#ifndef MADNESS_CHEM_POPULATION_H__INCLUDED
45#define MADNESS_CHEM_POPULATION_H__INCLUDED
46
48#include <nlohmann/json.hpp>
49
50#include <cstddef>
51#include <memory>
52#include <string>
53#include <vector>
54
55namespace madness {
56
57class World;
58class Molecule;
60template <typename T, std::size_t NDIM> class Function;
61
62namespace population {
63
64/// electrons per atom from one spin's occupied orbitals, with the scheme's diagnostics
66 Tensor<double> electrons; ///< electrons on each atom
67 Tensor<double> completeness; ///< mulliken/lowdin: c_i = X_i^T S^-1 X_i, the share of phi_i inside the basis
68 double spilling = 0.0; ///< mulliken/lowdin: 1 - sum_i n_i c_i / sum_i n_i (Sanchez-Portal et al. 1995)
69 double min_w_eigenvalue = 0.0; ///< smallest eigenvalue of W = X^T S^-1 X (all schemes)
70 double max_norm_error = 0.0; ///< iao: max_i |sum_rho Q_rho,i^2 - 1|, zero when phi lies in the IAO span
71};
72
73/// S^p of a symmetric positive semidefinite matrix; eigenvalues below tol * (largest) are dropped
74/// (for p < 0: the pseudo-inverse power on the retained space)
75Tensor<double> matrix_power(const Tensor<double>& S, double p, double tol = 1.e-12);
76
77/// Mulliken or Loewdin populations of the occupied space projected onto the basis
78
79/// The fit of phi_i onto the basis is C_i = S^-1 X_i; the fitted orbitals overlap as
80/// W = C^T S C = X^T S^-1 X, whose diagonal c_i <= 1 is each orbital's completeness. The
81/// fits are orthonormalized among themselves, Cbar = C W^-1/2 (the depolarized orbitals of
82/// the IAO construction), so the electrons sum to sum_i n_i and what the basis misses shows
83/// as the spilling instead:
84/// mulliken: N_mu = sum_i n_i (Cbar_i o S Cbar_i)_mu
85/// lowdin: N_mu = sum_i n_i ((S^1/2 Cbar_i)_mu)^2
86/// Both are invariant under rotations among equally occupied orbitals. (Renormalizing each
87/// fit by its own c_i also gives the sum rule, but not that invariance.)
88/// @param[in] scheme "mulliken" or "lowdin"
89SpinPopulation projection_population(const std::string& scheme, const Tensor<double>& S, const Tensor<double>& X,
90 const Tensor<double>& occ, const std::vector<int>& atom_of_bf, long natom);
91
92/// populations of the intrinsic atomic orbitals (Knizia, J. Chem. Theory Comput. 9, 4834 (2013))
93
94/// For a complete large basis (MRA) the IAOs follow from S and X of a minimal basis alone:
95/// W = X^T S^-1 X, D = S^-1 X W^-1/2 (the depolarized orbitals chi D)
96/// M = 1 - D D^T S, K = X^T (2 D D^T S - 1)
97/// A = chi M + phi K (the IAOs), <A|A> = M^T S M + M^T X K + K^T X^T M + K^T K, <A|phi> = M^T X + K^T
98/// Q = <A|A>^-1/2 <A|phi>, N_rho = sum_i n_i Q_rho,i^2
99/// The orbitals lie in the IAO span, so every column of Q has unit norm and the electrons
100/// sum to sum_i n_i to the precision of the overlaps. Throws when W is singular: the minimal
101/// basis then misses an orbital's atomic character.
103 const std::vector<int>& atom_of_bf, long natom);
104
105/// dispatch: "mulliken" and "lowdin" to projection_population, "iao" to iao_population
106SpinPopulation spin_population(const std::string& scheme, const Tensor<double>& S, const Tensor<double>& X,
107 const Tensor<double>& occ, const std::vector<int>& atom_of_bf, long natom);
108
109/// the schemes this file implements
110const std::vector<std::string>& schemes();
111
112/// one scheme's atomic charges and spin populations for a molecule
114 std::string scheme; ///< mulliken, lowdin or iao
115 std::string basis; ///< the projection or minimal basis set
116 long nbf = 0; ///< its number of functions
117 long nalpha = 0, nbeta = 0; ///< electrons of each spin
118 std::vector<std::string> symbols; ///< element of each atom
119 std::vector<double> charge; ///< q_A = Z_A - N_A(alpha) - N_A(beta)
120 std::vector<double> spin; ///< N_A(alpha) - N_A(beta)
121 SpinPopulation alpha, beta; ///< the per-spin results with their diagnostics
122
123 bool open() const { return nalpha != nbeta; }
124
125 /// the table (charge, and spin for open shells, per atom), the sums and the scheme's diagnostics
126 void print(double total_charge, int print_level) const;
127
128 nlohmann::json to_json() const;
129};
130
131/// charges and spin populations from the populations of both spins (beta empty when nbeta is 0)
132AtomicPopulations atomic_populations(const std::string& scheme, const std::string& basis, long nbf,
133 const std::vector<std::string>& symbols, const std::vector<double>& Z,
134 long nalpha, long nbeta, const SpinPopulation& alpha,
135 const SpinPopulation& beta);
136
137/// the population analysis of the population keys, for orbitals given in real space
138
139/// For each scheme of the `population` key: reads the basis set by name (population_basis
140/// for mulliken and lowdin, population_minbasis for iao), projects it at the current
141/// FunctionDefaults, forms S and X, and prints a table per scheme on rank 0 at print_level > 0.
142/// The occupied orbitals are those with a nonzero occupation, so explicit holes count, and
143/// the total charge is the nuclear charge minus their sum. The schemes assume orthonormal
144/// orbitals; after an SCF they are so only to its screening and truncation, so they are
145/// orthonormalized first (Loewdin, orthonormalize_symmetric). A failing scheme only warns:
146/// its entry in the result holds the error. moldft (SCF::population_analysis) and nemo
147/// (Nemo::population_analysis) call it after the final rung.
149public:
150 /// the schemes and basis sets of the population keys; nothing is projected yet
152
153 bool requested() const; ///< false for `population none`
154
155 /// closed shell: both spins have the orbitals mo with the occupations occ
156 /// @return the results on every rank; empty when not requested()
157 nlohmann::json analyze(const std::vector<Function<double,3>>& mo, const Tensor<double>& occ) const;
158
159 /// open shell
160 nlohmann::json analyze(const std::vector<Function<double,3>>& amo, const Tensor<double>& aocc,
161 const std::vector<Function<double,3>>& bmo, const Tensor<double>& bocc) const;
162
163private:
165 std::shared_ptr<const Molecule> molecule_; ///< a copy: the results refer to this geometry
166 std::vector<std::string> schemes_; ///< the population key
167 std::string basis_, minbasis_; ///< population_basis, population_minbasis
169
170 nlohmann::json run(const std::vector<Function<double,3>>& amo, const Tensor<double>& aocc,
171 const std::vector<Function<double,3>>& bmo, const Tensor<double>& bocc,
172 bool restricted) const;
173};
174
175} // namespace population
176} // namespace madness
177
178#endif // MADNESS_CHEM_POPULATION_H__INCLUDED
A multiresolution adaptive numerical function.
Definition mra.h:140
Definition molecule.h:129
A tensor is a multidimensional array.
Definition tensor.h:318
A parallel world class.
Definition world.h:134
the population analysis of the population keys, for orbitals given in real space
Definition population.h:148
int print_level_
Definition population.h:168
std::string minbasis_
population_basis, population_minbasis
Definition population.h:167
std::string basis_
Definition population.h:167
nlohmann::json analyze(const std::vector< Function< double, 3 > > &amo, const Tensor< double > &aocc, const std::vector< Function< double, 3 > > &bmo, const Tensor< double > &bocc) const
open shell
nlohmann::json run(const std::vector< Function< double, 3 > > &amo, const Tensor< double > &aocc, const std::vector< Function< double, 3 > > &bmo, const Tensor< double > &bocc, bool restricted) const
Definition population.cc:317
World & world_
Definition population.h:164
std::shared_ptr< const Molecule > molecule_
a copy: the results refer to this geometry
Definition population.h:165
nlohmann::json analyze(const std::vector< Function< double, 3 > > &mo, const Tensor< double > &occ) const
std::vector< std::string > schemes_
the population key
Definition population.h:166
bool requested() const
false for population none
Definition population.cc:301
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition derivatives.cc:72
const double beta
Definition gygi_soltion.cc:62
const std::vector< std::string > & schemes()
the schemes this file implements
Definition population.cc:75
SpinPopulation spin_population(const std::string &scheme, const Tensor< double > &S, const Tensor< double > &X, const Tensor< double > &occ, const std::vector< int > &atom_of_bf, const long natom)
dispatch: "mulliken" and "lowdin" to projection_population, "iao" to iao_population
Definition population.cc:192
AtomicPopulations atomic_populations(const std::string &scheme, const std::string &basis, const long nbf, const std::vector< std::string > &symbols, const std::vector< double > &Z, const long nalpha, const long nbeta, const SpinPopulation &alpha, const SpinPopulation &beta)
charges and spin populations from the populations of both spins (beta empty when nbeta is 0)
Definition population.cc:199
SpinPopulation iao_population(const Tensor< double > &S, const Tensor< double > &X, const Tensor< double > &occ, const std::vector< int > &atom_of_bf, const long natom)
populations of the intrinsic atomic orbitals (Knizia, J. Chem. Theory Comput. 9, 4834 (2013))
Definition population.cc:144
Tensor< double > matrix_power(const Tensor< double > &S, const double p, const double tol)
Definition population.cc:81
SpinPopulation projection_population(const std::string &scheme, const Tensor< double > &S, const Tensor< double > &X, const Tensor< double > &occ, const std::vector< int > &atom_of_bf, const long natom)
Mulliken or Loewdin populations of the occupied space projected onto the basis.
Definition population.cc:95
Namespace for all elements and tools of MADNESS.
Definition DFConvergence.h:9
@ mo
moldft orbitals psi
static double Z
Definition rk.cc:35
Definition mcpfit.cc:241
Definition CalculationParameters.h:51
one scheme's atomic charges and spin populations for a molecule
Definition population.h:113
long nbeta
electrons of each spin
Definition population.h:117
std::string scheme
mulliken, lowdin or iao
Definition population.h:114
bool open() const
Definition population.h:123
long nalpha
Definition population.h:117
SpinPopulation alpha
Definition population.h:121
std::vector< double > spin
N_A(alpha) - N_A(beta)
Definition population.h:120
std::string basis
the projection or minimal basis set
Definition population.h:115
SpinPopulation beta
the per-spin results with their diagnostics
Definition population.h:121
std::vector< std::string > symbols
element of each atom
Definition population.h:118
std::vector< double > charge
q_A = Z_A - N_A(alpha) - N_A(beta)
Definition population.h:119
long nbf
its number of functions
Definition population.h:116
nlohmann::json to_json() const
Definition population.cc:262
void print(double total_charge, int print_level) const
the table (charge, and spin for open shells, per atom), the sums and the scheme's diagnostics
Definition population.cc:225
electrons per atom from one spin's occupied orbitals, with the scheme's diagnostics
Definition population.h:65
double max_norm_error
iao: max_i |sum_rho Q_rho,i^2 - 1|, zero when phi lies in the IAO span
Definition population.h:70
double spilling
mulliken/lowdin: 1 - sum_i n_i c_i / sum_i n_i (Sanchez-Portal et al. 1995)
Definition population.h:68
Tensor< double > electrons
electrons on each atom
Definition population.h:66
Tensor< double > completeness
mulliken/lowdin: c_i = X_i^T S^-1 X_i, the share of phi_i inside the basis
Definition population.h:67
double min_w_eigenvalue
smallest eigenvalue of W = X^T S^-1 X (all schemes)
Definition population.h:69
InputParameters param
Definition tdse.cc:203
Defines and implements most of Tensor.
static const double alpha
Definition testcosine.cc:10
static Molecule molecule
Definition testperiodicdft.cc:39