1 #pragma once
2 
3 #include <stddef.h>
4 #include "simint/ostei/ostei_config.h"
5 
6 
7 #define SIMINT_SCREEN_NONE         0
8 #define SIMINT_SCREEN_SCHWARZ      1
9 #define SIMINT_SCREEN_FASTSCHWARZ  2
10 
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 
17 /*! \brief Information about a gaussian shell */
18 struct simint_shell
19 {
20     int am;          //!< Angular momentum (0 = s, etc)
21     int nprim;       //!< Number of primitives in this shell
22 
23     double x;        //!< X coordinate (in bohr)
24     double y;        //!< Y coordinate (in bohr)
25     double z;        //!< Z coordinate (in bohr)
26 
27     double * alpha;  //!< Exponents of the gaussian functions (for each primitive)
28     double * coef;   //!< Contraction coefficients (for each primitive)
29 
30     size_t memsize;     //!< Total memory for storing various data in this structure (in bytes)
31     void * ptr;      //!< Pointer to all the allocated memory within this structure (in bytes)
32 };
33 
34 
35 /*! \brief A structure holding information about multiple shell pair
36  *
37  * A shell pair is a combination of two gaussian shells occuring in the bra
38  * or ket of an integral. Several factors used in calculation of integrals
39  * can be computed solely from a pair of shells (that is, it doesn't require
40  * information from all four centers). This include some factors from the
41  * gaussian product theorem.
42  *
43  * The only real requirement is that all shells in the first position have the
44  * same angular momentum, and all shells in the second position have the same
45  * angular momentum.
46  */
47 struct simint_multi_shellpair
48 {
49     int am1;            //!< Angular momentum of the first position
50     int am2;            //!< Angular momentum of the second position
51     int nprim;          //!< Total number of primitive combinations stored (not including padding)
52 
53     int nshell12;       //!< Total number of shell pair (nshell1 * nshell2)
54     int nshell12_clip;  //!< Total number of shell pair to actual calculate (should be <= nshell12)
55     int * nprim12;      //!< Number of primitive combinations for each shell pair, not including padding (length nshell12)
56 
57     double * AB_x;      //!< X distance between the centers for a shell (Ax - Bx) (length nshell12).
58     double * AB_y;      //!< Y distance between the centers for a shell (Ay - By) (length nshell12).
59     double * AB_z;      //!< Z distance between the centers for a shell (Az - Bz) (length nshell12).
60 
61     double * x;         //!< X coordinate of each primitive pair (from GPT)
62     double * y;         //!< y coordinate of each primitive pair (from GPT)
63     double * z;         //!< z coordinate of each primitive pair (from GPT)
64     double * PA_x;      //!< Px - Ax
65     double * PA_y;      //!< Py - Ay
66     double * PA_z;      //!< Pz - Az
67     double * PB_x;      //!< Px - Bx
68     double * PB_y;      //!< Py - By
69     double * PB_z;      //!< Pz - Bz
70 
71     double * alpha;     //!< New coefficients (from GPT)
72 
73     #if SIMINT_OSTEI_MAXDER > 0
74     double * alpha2;    //!< 2*exponent on the first center
75     double * beta2;     //!< 2*exponent on the second center
76     #endif
77 
78     double * prefac;    //!< Prefactors for each primitive pair, including coefficients and other factors
79     double * screen;    //!< Screening information (value of g_{abab} for all primitive shell pair)
80     double screen_max;  //!< Maximum value in the screen array
81 
82 
83     size_t memsize;     //!< Total memory for storing various data in this structure (in bytes)
84     void * ptr;         //!< Pointer to all the allocated memory within this structure (length memsize)
85 };
86 
87 
88 /*! \brief See if two shells are equivalent */
89 static inline
compare_shell(struct simint_shell const * A,struct simint_shell const * B)90 int compare_shell(struct simint_shell const * A,
91                   struct simint_shell const * B)
92 {
93     return A->nprim == B->nprim && A->ptr == B->ptr;
94 }
95 
96 
97 /*! \brief Initialize a shell structure
98  *
99  * This sets certain values to zero so that they can be used with
100  * simint_allocate_shell, etc.
101  *
102  * \param [inout] G The structure to initialize
103  */
104 void simint_initialize_shell(struct simint_shell * G);
105 
106 
107 /*! \brief Initialize an array of shell structures
108  *
109  * This sets certain values to zero so that they can be used with
110  * simint_allocate_shell, etc.
111  *
112  * \param [in] n Number of shell structures to initialize
113  * \param [inout] G An array of shell structures to initialize
114  */
115 void simint_initialize_shells(int n, struct simint_shell * G);
116 
117 
118 /*! \brief Allocate memory in a shell
119  *
120  * Allocate enough memory for the exponents and coefficients, and sets up
121  * the \p alpha and \coef pointers. This also sets the \p ptr and \p memsize
122  * members of \p G
123  */
124 void simint_allocate_shell(int nprim, struct simint_shell * G);
125 
126 
127 /*! \brief Frees memory associated with a shell structure
128  *
129  * The \p ptr member will be set to NULL and the memsize will be set to zero.
130  */
131 void simint_free_shell(struct simint_shell * G);
132 
133 
134 /*! \brief Frees memory associated with shell structures
135  *
136  * The \p ptr member will be set to NULL and the memsize will be set to zero.
137  *
138  * \param [in] n Number of shell structures to free
139  * \param [inout] G An array of shell structures to free
140  */
141 void simint_free_shells(int n, struct simint_shell * G);
142 
143 
144 /*! \brief Copies a shell structure
145  *
146  * Memory will be allocated for a new shell and all the data copied from \p src
147  * to \p dest
148  */
149 void simint_copy_shell(struct simint_shell const * src,
150                        struct simint_shell * dest);
151 
152 
153 /*! \brief Normalize the coefficients of shells
154  *
155  * The normalization in this function is what is expected in the simint library
156  *
157  * \param [in] n The number of shells to normalize
158  * \param [inout] G Pointer to the shells to normalize
159  */
160 void simint_normalize_shells(int n, struct simint_shell * G);
161 
162 
163 /*! \brief Create a simint shell
164  *
165  * Just for convenience. You may also allocate and then
166  * manually fill in the data members yourself.
167  *
168  * \p G must be initialized, but does not need to be
169  * allocated.
170  *
171  * Data will be copied from the \p alpha and \p coef
172  * pointers.
173  *
174  * The shell must be freed later (via simint_free_shell)
175  *
176  * \param [in] nprim Number of primitives in the shell
177  * \param [in] am Angular momentum of the shell
178  * \param [in] x The x-coordinate of the shell
179  * \param [in] y The y-coordinate of the shell
180  * \param [in] z The z-coordinate of the shell
181  * \param [in] alpha The alpha parameters of the primitives
182  * \param [in] coef The coefficients of the primitives
183  * \param [inout] G The gaussian shell to use
184  */
185 void simint_create_shell(int nprim, int am, double x, double y, double z,
186                          double const * alpha,
187                          double const * coef,
188                          struct simint_shell * G);
189 
190 
191 
192 /*! \brief Create a dummy simint_shell
193  *
194  * This can be used to represent non-existent shells (for example,
195  * for 3-center and 2-center integrals
196  *
197  * \p G must be initialized, but does not need to be allocated or filled.
198  * If it is already filled, any existing data in \p G is overwritten.
199  *
200  * \param [inout] The gaussian shell to create
201  */
202 void simint_create_zero_shell(struct simint_shell * G);
203 
204 
205 /*! \brief Initialize a shell pair structure
206  *
207  * This sets certain values to zero so that they can be used with
208  * simint_allocate_multi_shellpair, etc.
209  *
210  * \param [inout] P The structure to initialize
211  */
212 void simint_initialize_multi_shellpair(struct simint_multi_shellpair * P);
213 
214 
215 /*! \brief Initialize an array of shell pair structure
216  *
217  * This sets certain values to zero so that they can be used with
218  * simint_allocate_multi_shellpair, etc.
219  *
220  * \param [in] n Number of shell pair structures to initialize
221  * \param [inout] P An array of shell pair structures to initialize
222  */
223 void simint_initialize_multi_shellpairs(int n, struct simint_multi_shellpair * P);
224 
225 
226 /*! \brief Allocate space in a multi shellpair structure
227  *
228  * Only sets up the pointers in \P and fills in the \p memsize and \p ptr members.
229  *
230  * \param [in] na Number of shells in the first position
231  * \param [in] A Shells that will be stored in the first position of this multi_shellpair
232  * \param [in] nb Number of shells in the second position
233  * \param [in] B Shells that will be stored in the second position of this multi_shellpair
234  * \param [inout] P The structure in which to allocate the memory
235  */
236 void simint_allocate_multi_shellpair(int na, struct simint_shell const * A,
237                                      int nb, struct simint_shell const * B,
238                                      struct simint_multi_shellpair * P,
239                                      int screen_method);
240 
241 
242 /*! \brief Allocate space in a multi shellpair structure
243  *
244  * Only sets up the pointers in \P and fills in the \p memsize and \p ptr members.
245  *
246  * \param [in] npair Number of shell pairs in the array
247  * \param [in] AB Pairs of shells to place in the shell pair
248  * \param [inout] P The structure in which to allocate the memory
249  */
250 void simint_allocate_multi_shellpair2(int npair, struct simint_shell const * AB,
251                                       struct simint_multi_shellpair * P,
252                                       int screen_method);
253 
254 
255 /*! \brief Frees memory associated with a multi shellpair structure
256  *
257  * The \p ptr member will be set to NULL and the memsize will be set to zero.
258  */
259 void simint_free_multi_shellpair(struct simint_multi_shellpair * P);
260 
261 
262 /*! \brief Frees memory associated with an array of multi shellpair structure
263  *
264  * The \p ptr member will be set to NULL and the memsize will be set to zero.
265  *
266  * \param [in] n Number of shell pair structures to free
267  * \param [inout] P An array of shell pair structures to free
268  */
269 void simint_free_multi_shellpairs(int n, struct simint_multi_shellpair * P);
270 
271 
272 /*! \brief Computes and fills in values for a multi shellpair
273  *
274  * This calculates the values for all the members of a simint_multishellpair structure by
275  * looping over all combinations of A and B and forming the shell pair information.
276  *
277  * \param [in] na Number of shells in the first position
278  * \param [in] A Shells in the first position of this multi_shellpair
279  * \param [in] nb Number of shells in the second position
280  * \param [in] B Shells in the second position of this multi_shellpair
281  * \param [inout] P The structure that will hold the shell pair data
282  *
283  * \warning \p P must already be allocated (via simint_allocate_multi_shellpair)
284  */
285 void simint_fill_multi_shellpair(int na, struct simint_shell const * A,
286                                  int nb, struct simint_shell const * B,
287                                  struct simint_multi_shellpair * P,
288                                  int screen_method);
289 
290 
291 /*! \brief Computes and fills in values for a multi shellpair
292  *
293  * This calculates the values for all the members of a simint_multishellpair structure by
294  * looping through the array of pairs.
295  *
296  * The array is expected to be 2*npair in length, with the pairs being adjacent. Ie,
297  *
298  * AB = [A1 B1 A1 B2 A2 B1 A2 B2]  with npair = 4
299  *
300  * \param [in] npair Number of shell pairs in the array
301  * \param [in] AB Pairs of shells to place in the shell pair
302  * \param [inout] P The structure that will hold the shell pair data
303  * \param [in] screen_method Screening method for primitives
304  *
305  * \warning \p P must already be allocated (via simint_allocate_multi_shellpair)
306  */
307 void simint_fill_multi_shellpair2(int npair, struct simint_shell const * AB,
308                                   struct simint_multi_shellpair * P,
309                                   int screen_method);
310 
311 
312 /*! \brief Allocates and fills a multi shellpair structure
313  *
314  * For convenience. Creates a new simint_multi_shellpair structure,
315  * allocates it, and then calculates all the data.
316  *
317  * \param [in] na Number of shells in the first position
318  * \param [in] A Shells in the first position of this multi_shellpair
319  * \param [in] nb Number of shells in the second position
320  * \param [in] B Shells in the second position of this multi_shellpair
321  * \param [inout] P The structure that will hold the shell pair data
322  * \param [in] screen_method Screening method for primitives
323  */
324 void
325 simint_create_multi_shellpair(int na, struct simint_shell const * A,
326                               int nb, struct simint_shell const * B,
327                               struct simint_multi_shellpair * P,
328                               int screen_method);
329 
330 
331 /*! \brief Allocates and fills a multi shellpair structure
332  *
333  * For convenience. Creates a new simint_multi_shellpair structure,
334  * allocates it, and then calculates all the data.
335  *
336  * \param [in] npair Number of shell pairs in the array
337  * \param [in] AB Pairs of shells to place in the shell pair
338  * \param [inout] P The structure that will hold the shell pair data
339  * \param [in] screen_method Screening method for primitives
340  */
341 void
342 simint_create_multi_shellpair2(int npair,
343                                struct simint_shell const * AB,
344                                struct simint_multi_shellpair * P,
345                                int screen_method);
346 
347 
348 /*! \brief Combine existing multi shellpair structures into a new one
349  *
350  * Existing information in \Pout will be erased
351  *
352  * \param [in] nmpair Number of multi shellpair pointers in \p Pin
353  * \param [in] Pin Array of pointers to multi shellpair to combine
354  * \param [inout] Pout The structure that will hold the new shell pair data
355  * \param [in] screen_method Screening method for primitives
356  */
357 void simint_cat_multi_shellpair(int nmpair,
358                                 struct simint_multi_shellpair const ** Pin,
359                                 struct simint_multi_shellpair * Pout,
360                                 int screen_method);
361 
362 
363 /*! \brief Remove all insignificant primitive pairs
364  *
365  *
366  * \param [in] npair Number of shell pairs in the array
367  * \param [in] AB Pairs of shells to place in the shell pair
368  * \param [inout] P The structure that will hold the shell pair data
369  */
370 /*
371 void
372 simint_prune_multi_shellpair(struct simint_multi_shellpair const * P,
373                              struct simint_multi_shellpair * out,
374                              double screen_max, double screen_tol);
375 */
376 
377 #ifdef __cplusplus
378 }
379 #endif
380 
381