1 /******************************************************************************
2 
3   This source file is part of the Avogadro project.
4 
5   Copyright 2008-2009 Marcus D. Hanwell
6   Copyright 2010-2013 Kitware, Inc.
7 
8   This source code is released under the New BSD License, (the "License").
9 
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15 
16 ******************************************************************************/
17 
18 #ifndef AVOGADRO_CORE_SLATERSET_H
19 #define AVOGADRO_CORE_SLATERSET_H
20 
21 #include "basisset.h"
22 
23 #include <avogadro/core/matrix.h>
24 #include <avogadro/core/vector.h>
25 
26 #include <vector>
27 
28 namespace Avogadro {
29 namespace Core {
30 
31 /**
32  * @class SlaterSet slaterset.h
33  * @brief SlaterSet Class
34  * @author Marcus D. Hanwell
35  *
36  * The SlaterSet class has a transparent data structure for storing the basis
37  * sets output by many quantum mechanical codes. It has a certain hierarchy
38  * where shells are built up from n primitives, in this case Slater Type
39  * Orbitals (STOs). Each shell has a type (S, P, D, F, etc) and is composed of
40  * one or more STOs. Each STO has a contraction coefficient, c, and an exponent,
41  * a.
42  *
43  * When calculating Molecular Orbitals (MOs) each orthogonal shell has an
44  * independent coefficient. That is the S type orbitals have one coefficient,
45  * the P type orbitals have three coefficients (Px, Py and Pz), the D type
46  * orbitals have five (or six if cartesian types) coefficients, and so on.
47  */
48 
49 struct SlaterShell;
50 
51 class AVOGADROCORE_EXPORT SlaterSet : public BasisSet
52 {
53 public:
54   /**
55    * Constructor.
56    */
57   SlaterSet();
58 
59   /**
60    * Destructor.
61    */
62   ~SlaterSet() override;
63 
64   /**
65    * Clone.
66    */
clone()67   SlaterSet* clone() const override { return new SlaterSet(*this); }
68 
69   /**
70    * Enumeration of the Slater orbital types.
71    */
72   enum slater
73   {
74     S,
75     PX,
76     PY,
77     PZ,
78     X2,
79     XZ,
80     Z2,
81     YZ,
82     XY,
83     UU
84   };
85 
86   /**
87    * Add a basis to the basis set.
88    * @param i Index of the atom to add the Basis too.
89    * @return The index of the added Basis.
90    */
91   bool addSlaterIndices(const std::vector<int>& i);
92 
93   /**
94    * Add the symmetry types for the orbitals.
95    * @param t Vector containing the types of symmetry using the slater enum.
96    */
97   bool addSlaterTypes(const std::vector<int>& t);
98 
99   /**
100    * Add a STO to the supplied basis.
101    * @param zetas The exponents of the STOs
102    * @return True if successful.
103    */
104   bool addZetas(const std::vector<double>& zetas);
105 
106   /**
107    * The PQNs for the orbitals.
108    */
109   bool addPQNs(const std::vector<int>& pqns);
110 
111   /**
112    * The overlap matrix.
113    * @param m Matrix containing the overlap matrix for the basis.
114    */
115   bool addOverlapMatrix(const Eigen::MatrixXd& m);
116 
117   /**
118    * Add Eigen Vectors to the SlaterSet.
119    * @param e Matrix of the eigen vectors for the SlaterSet.
120    */
121   bool addEigenVectors(const Eigen::MatrixXd& e);
122 
123   /**
124    * Add the density matrix to the SlaterSet.
125    * @param d Density matrix for the SlaterSet.
126    */
127   bool addDensityMatrix(const Eigen::MatrixXd& d);
128 
129   /**
130    * @return The number of molecular orbitals in the BasisSet.
131    */
132   unsigned int molecularOrbitalCount(ElectronType type = Paired) override;
133 
134   /**
135    * @return True of the basis set is valid, false otherwise.
136    * Default is true, if false then the basis set is likely unusable.
137    */
isValid()138   bool isValid() override { return true; }
139 
140   /**
141    * Initialize the calculation, this must normally be done before anything.
142    */
143   void initCalculation();
144 
145   /**
146    * Accessors for the various properties of the GaussianSet.
147    */
slaterIndices()148   std::vector<int>& slaterIndices() { return m_slaterIndices; }
slaterTypes()149   std::vector<int>& slaterTypes() { return m_slaterTypes; }
zetas()150   std::vector<double>& zetas() { return m_zetas; }
factors()151   std::vector<double>& factors() { return m_factors; }
PQNs()152   std::vector<int>& PQNs() { return m_PQNs; }
normalizedMatrix()153   MatrixX& normalizedMatrix() { return m_normalized; }
densityMatrix()154   MatrixX& densityMatrix() { return m_density; }
155 
156   void outputAll();
157 
158 private:
159   std::vector<int> m_slaterIndices;
160   std::vector<int> m_slaterTypes;
161   std::vector<double> m_zetas;
162   std::vector<int> m_pqns, m_PQNs;
163 
164   std::vector<double> m_factors;
165   MatrixX m_overlap;
166   MatrixX m_eigenVectors;
167   MatrixX m_density;
168   MatrixX m_normalized;
169   bool m_initialized;
170 
171   unsigned int factorial(unsigned int n);
172 };
173 
174 } // End Core namespace
175 } // End Avogadro namespace
176 
177 #endif
178