1 /* Ergo, version 3.8, a program for linear scaling electronic structure
2  * calculations.
3  * Copyright (C) 2019 Elias Rudberg, Emanuel H. Rubensson, Pawel Salek,
4  * and Anastasia Kruchinina.
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 3 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, see <http://www.gnu.org/licenses/>.
18  *
19  * Primary academic reference:
20  * Ergo: An open-source program for linear-scaling electronic structure
21  * calculations,
22  * Elias Rudberg, Emanuel H. Rubensson, Pawel Salek, and Anastasia
23  * Kruchinina,
24  * SoftwareX 7, 107 (2018),
25  * <http://dx.doi.org/10.1016/j.softx.2018.03.005>
26  *
27  * For further information about Ergo, see <http://www.ergoscf.org>.
28  */
29 
30 /** @file integral_info.h
31 
32     @brief Defines IntegralInfo object, providing the coefficients
33     needed for integral evaluation.
34 
35     @author: Elias Rudberg <em>responsible</em>
36 */
37 
38 #ifndef BASISINFO_BASIC_HEADER
39 #define BASISINFO_BASIC_HEADER
40 
41 
42 #include "realtype.h"
43 #include "monomial_info.h"
44 #include "hermite_conversion_prep.h"
45 #include "boysfunction.h"
46 #include "multipole_prep.h"
47 #include "mm_limit_table.h"
48 
49 #ifndef BASIS_FUNC_POLY_MAX_DEGREE
50 #error The constant BASIS_FUNC_POLY_MAX_DEGREE must be defined.
51 #endif
52 #if BASIS_FUNC_POLY_MAX_DEGREE<6
53 #define MAX_NO_OF_TERMS_IN_BASIS_FUNC_POLY 12
54 #define MAX_NO_OF_POLY_12_TERMS 180
55 #define MAX_NO_OF_BASIS_FUNC_POLYS 50
56 #else
57 #define MAX_NO_OF_TERMS_IN_BASIS_FUNC_POLY 16
58 #define MAX_NO_OF_POLY_12_TERMS 360
59 #define MAX_NO_OF_BASIS_FUNC_POLYS 100
60 #endif
61 
62 typedef struct
63 {
64   ergo_real coeff;
65   char monomialInts[4];  /* nx, ny, nz    */
66   int monomialID;
67 } basis_func_term_struct;
68 
69 typedef struct
70 {
71   int noOfTerms;
72   basis_func_term_struct termList[MAX_NO_OF_TERMS_IN_BASIS_FUNC_POLY];
73   ergo_real scaledSolidHarmonicPrefactor;
74 } basis_func_poly_struct;
75 
76 typedef struct
77 {
78   int id_1;
79   int id_2;
80   ergo_real coeff;
81 } poly_12_term_struct;
82 
83 typedef struct
84 {
85   int noOfTerms;
86   poly_12_term_struct termList[MAX_NO_OF_POLY_12_TERMS];
87 } poly_12_struct;
88 
89 /** Contains coefficients needed for quick integral evaluation. This
90     object is quite large and should always be allocated with
91     new. Placing it on stack is a bad idea. */
92 
93 class IntegralInfo
94 {
95  private:
96   BoysFunctionManager boysFunctionManager;
97   MultipolePrepManager multipolePrep;
98   MMLimitTable mmLimitTable;
99   hermite_conversion_info_struct hermite_conversion_info;
100   bool initialized;
101   IntegralInfo(); // This is to make it forbidden to create it without argument.
102  public:
103   basis_func_poly_struct basis_func_poly_list[MAX_NO_OF_BASIS_FUNC_POLYS];
104   int no_of_basis_func_polys;
105   monomial_info_struct monomial_info;
106   void init();
107   ergo_real BoysFunction(int n, ergo_real x) const;
108   ergo_real BoysFunction_expensive(int n, ergo_real x, int noOfIntegrationIntervals) const;
GetMultipolePrep()109   const MultipolePrepManager & GetMultipolePrep() const { return multipolePrep; }
GetMMLimitTable()110   const MMLimitTable & GetMMLimitTable() const { return mmLimitTable; }
111   int multiply_by_hermite_conversion_matrix_from_right(int n1max,
112 						       int n2max,
113 						       ergo_real a,
114 						       ergo_real* A,
115 						       ergo_real* result) const;
116   int multiply_by_hermite_conversion_matrix_from_left(int n1max,
117 						      int n2max,
118 						      ergo_real a,
119 						      ergo_real* A,
120 						      ergo_real* result) const;
121   int get_hermite_conversion_matrix_right(int nmax,
122 					  ergo_real a,
123 					  ergo_real* result) const;
124   int get_hermite_conversion_matrix_left(int nmax,
125 					 ergo_real a,
126 					 ergo_real* result) const;
127   int get_hermite_conversion_matrix_right_sparse(int nmax,
128                                                  ergo_real a,
129                                                  i_j_val_struct* result) const;
130 
131   IntegralInfo(bool initialize);
132   ~IntegralInfo();
133 
134   // Stuff needed for Chunks&Tasks usage
135   IntegralInfo(const IntegralInfo & ii);
136   void write_to_buffer ( char * dataBuffer, size_t const bufferSize ) const;
137   size_t get_size() const;
138   void assign_from_buffer ( char const * dataBuffer, size_t const bufferSize);
139 };
140 
141 
142 namespace JK {
143 /* Struct ExchWeights holds parameters for CAM-style range-separated HF
144    exchange.  We use the following short-long range split
145    (alpha+beta*erf(mu*r))*HF_exchange.
146  */
147 struct ExchWeights
148 {
149   ergo_real alpha;
150   ergo_real beta;
151   ergo_real mu;
152   int computeRangeSeparatedExchange; /**< shortcut for |beta| != 0 */
153 
ExchWeightsExchWeights154 ExchWeights() :
155   alpha(0),
156     beta(0),
157     mu(0),
158     computeRangeSeparatedExchange(0)
159   {}
160 
161 };
162 
163 }
164 
165 
166 int get_poly_info_from_shell_type(int* polyid_start, int* poly_count, int shellType);
167 
168 int get_no_of_basis_func_polys_used_from_no_of_shell_types(int no_of_shell_types);
169 
170 int get_shell_type_from_basis_func_poly_id(int basfuncpolyid);
171 
172 
173 #endif
174