1 //
2 // tbint.h
3 //
4 // Copyright (C) 1996 Limit Point Systems, Inc.
5 //
6 // Author: Edward Seidl <seidl@janed.com>
7 // Maintainer: LPS
8 //
9 // This file is part of the SC Toolkit.
10 //
11 // The SC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The SC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27 
28 #ifndef _chemistry_qc_basis_tbint_h
29 #define _chemistry_qc_basis_tbint_h
30 
31 #ifdef __GNUC__
32 #pragma interface
33 #endif
34 
35 #include <util/ref/ref.h>
36 #include <util/group/message.h>
37 #include <chemistry/qc/basis/gaussbas.h>
38 #include <chemistry/qc/basis/dercent.h>
39 
40 namespace sc {
41 
42 // //////////////////////////////////////////////////////////////////////////
43 
44 class Integral;
45 
46 /** This is an abstract base type for classes that
47     compute integrals involving two electrons.
48  */
49 class TwoBodyInt : public RefCount {
50   protected:
51     // this is who created me
52     Integral *integral_;
53 
54     Ref<GaussianBasisSet> bs1_;
55     Ref<GaussianBasisSet> bs2_;
56     Ref<GaussianBasisSet> bs3_;
57     Ref<GaussianBasisSet> bs4_;
58 
59     double *buffer_;
60 
61     int redundant_;
62 
63     TwoBodyInt(Integral *integral,
64                const Ref<GaussianBasisSet>&bs1,
65                const Ref<GaussianBasisSet>&bs2,
66                const Ref<GaussianBasisSet>&bs3,
67                const Ref<GaussianBasisSet>&bs4);
68   public:
69     virtual ~TwoBodyInt();
70 
71     /// Return the number of basis functions on center one.
72     int nbasis() const;
73 
74     /// Return the number of basis functions on center one.
75     int nbasis1() const;
76     /// Return the number of basis functions on center two.
77     int nbasis2() const;
78     /// Return the number of basis functions on center three.
79     int nbasis3() const;
80     /// Return the number of basis functions on center four.
81     int nbasis4() const;
82 
83     /// Return the number of shells on center one.
84     int nshell() const;
85 
86     /// Return the number of shells on center one.
87     int nshell1() const;
88     /// Return the number of shells on center two.
89     int nshell2() const;
90     /// Return the number of shells on center three.
91     int nshell3() const;
92     /// Return the number of shells on center four.
93     int nshell4() const;
94 
95     /// Return the basis set on center one.
96     Ref<GaussianBasisSet> basis();
97 
98     /// Return the basis set on center one.
99     Ref<GaussianBasisSet> basis1();
100     /// Return the basis set on center two.
101     Ref<GaussianBasisSet> basis2();
102     /// Return the basis set on center three.
103     Ref<GaussianBasisSet> basis3();
104     /// Return the basis set on center four.
105     Ref<GaussianBasisSet> basis4();
106 
107   /** Types of two-body integrals that TwoBodyInt understands:
108       eri stands for electron repulsion integral, r12 stands for integrals
109       of r12 operator, r12t1 and r12t2 are integrals of [r12,T1] and
110       [r12,T2] operators */
111     enum tbint_type { eri=0, r12=1, r12t1=2, r12t2=3};
112   /// The total number of such types
113     static const int num_tbint_types = 4;
114 
115     /** The computed shell integrals will be put in the buffer returned
116         by this member.  Some TwoBodyInt specializations have more than
117 	one buffer:  The type arguments selects which buffer is returned.
118 	If the requested type is not supported, then 0 is returned. */
119     virtual const double * buffer(tbint_type type = eri) const;
120 
121     /** Given four shell indices, integrals will be computed and placed in
122         the buffer.  The first two indices correspond to electron 1 and the
123         second two indices correspond to electron 2.*/
124     virtual void compute_shell(int,int,int,int) = 0;
125 
126     /** Return log base 2 of the maximum magnitude of any integral in a
127         shell block obtained from compute_shell.  An index of -1 for any
128         argument indicates any shell.  */
129     virtual int log2_shell_bound(int= -1,int= -1,int= -1,int= -1) = 0;
130 
131     /** If redundant is true, then keep redundant integrals in the buffer.
132         The default is true. */
redundant()133     virtual int redundant() const { return redundant_; }
134     /// See redundant().
set_redundant(int i)135     virtual void set_redundant(int i) { redundant_ = i; }
136 
137     /// This storage is used to cache computed integrals.
138     virtual void set_integral_storage(size_t storage);
139 
140     /// Return the integral factory that was used to create this object.
integral()141     Integral *integral() const { return integral_; }
142 
143 };
144 
145 // //////////////////////////////////////////////////////////////////////////
146 
147 /** This is an abstract base type for classes that compute integrals
148     involving two electrons in three Gaussian functions.
149  */
150 class TwoBodyThreeCenterInt : public RefCount {
151   protected:
152     // this is who created me
153     Integral *integral_;
154 
155     Ref<GaussianBasisSet> bs1_;
156     Ref<GaussianBasisSet> bs2_;
157     Ref<GaussianBasisSet> bs3_;
158 
159     double *buffer_;
160 
161     int redundant_;
162 
163     TwoBodyThreeCenterInt(Integral *integral,
164                           const Ref<GaussianBasisSet>&bs1,
165                           const Ref<GaussianBasisSet>&bs2,
166                           const Ref<GaussianBasisSet>&bs3);
167   public:
168     virtual ~TwoBodyThreeCenterInt();
169 
170     /// Return the number of basis functions on center one.
171     int nbasis() const;
172 
173     /// Return the number of basis functions on center one.
174     int nbasis1() const;
175     /// Return the number of basis functions on center two.
176     int nbasis2() const;
177     /// Return the number of basis functions on center three.
178     int nbasis3() const;
179 
180     /// Return the number of shells on center one.
181     int nshell() const;
182 
183     /// Return the number of shells on center one.
184     int nshell1() const;
185     /// Return the number of shells on center two.
186     int nshell2() const;
187     /// Return the number of shells on center three.
188     int nshell3() const;
189 
190     /// Return the basis set on center one.
191     Ref<GaussianBasisSet> basis();
192 
193     /// Return the basis set on center one.
194     Ref<GaussianBasisSet> basis1();
195     /// Return the basis set on center two.
196     Ref<GaussianBasisSet> basis2();
197     /// Return the basis set on center three.
198     Ref<GaussianBasisSet> basis3();
199 
200   /** Types of two-body integrals that TwoBodyInt understands:
201       eri stands for electron repulsion integral, r12 stands for integrals
202       of r12 operator, r12t1 and r12t2 are integrals of [r12,T1] and
203       [r12,T2] operators */
204     enum tbint_type { eri=0, r12=1, r12t1=2, r12t2=3};
205   /// The total number of such types
206     static const int num_tbint_types = 4;
207 
208     /** The computed shell integrals will be put in the buffer returned
209         by this member.  Some TwoBodyInt specializations have more than
210 	one buffer:  The type arguments selects which buffer is returned.
211 	If the requested type is not supported, then 0 is returned. */
212     virtual const double * buffer(tbint_type type = eri) const;
213 
214     /** Given three shell indices, integrals will be computed and placed in
215         the buffer.  The first two indices correspond to electron 1 and the
216         second index corresponds to electron 2.*/
217     virtual void compute_shell(int,int,int) = 0;
218 
219     /** Return log base 2 of the maximum magnitude of any integral in a
220         shell block obtained from compute_shell.  An index of -1 for any
221         argument indicates any shell.  */
222     virtual int log2_shell_bound(int= -1,int= -1,int= -1) = 0;
223 
224     /** If redundant is true, then keep redundant integrals in the buffer.
225         The default is true. */
redundant()226     int redundant() const { return redundant_; }
227     /// See redundant().
set_redundant(int i)228     void set_redundant(int i) { redundant_ = i; }
229 
230     /// This storage is used to cache computed integrals.
231     virtual void set_integral_storage(size_t storage);
232 
233     /// Return the integral factory that was used to create this object.
integral()234     Integral *integral() const { return integral_; }
235 
236 };
237 
238 // //////////////////////////////////////////////////////////////////////////
239 
240 /** This is an abstract base type for classes that
241     compute integrals involving two electrons in two
242     Gaussian functions.
243  */
244 class TwoBodyTwoCenterInt : public RefCount {
245   protected:
246     // this is who created me
247     Integral *integral_;
248 
249     Ref<GaussianBasisSet> bs1_;
250     Ref<GaussianBasisSet> bs2_;
251 
252     double *buffer_;
253 
254     int redundant_;
255 
256     TwoBodyTwoCenterInt(Integral *integral,
257                         const Ref<GaussianBasisSet>&bs1,
258                         const Ref<GaussianBasisSet>&bs2);
259   public:
260     virtual ~TwoBodyTwoCenterInt();
261 
262     /// Return the number of basis functions on center one.
263     int nbasis() const;
264 
265     /// Return the number of basis functions on center one.
266     int nbasis1() const;
267     /// Return the number of basis functions on center two.
268     int nbasis2() const;
269 
270     /// Return the number of shells on center one.
271     int nshell() const;
272 
273     /// Return the number of shells on center one.
274     int nshell1() const;
275     /// Return the number of shells on center two.
276     int nshell2() const;
277 
278     /// Return the basis set on center one.
279     Ref<GaussianBasisSet> basis();
280 
281     /// Return the basis set on center one.
282     Ref<GaussianBasisSet> basis1();
283     /// Return the basis set on center two.
284     Ref<GaussianBasisSet> basis2();
285 
286   /** Types of two-body integrals that TwoBodyInt understands:
287       eri stands for electron repulsion integral, r12 stands for integrals
288       of r12 operator, r12t1 and r12t2 are integrals of [r12,T1] and
289       [r12,T2] operators */
290     enum tbint_type { eri=0, r12=1, r12t1=2, r12t2=3};
291   /// The total number of such types
292     static const int num_tbint_types = 4;
293 
294     /** The computed shell integrals will be put in the buffer returned
295         by this member.  Some TwoBodyInt specializations have more than
296 	one buffer:  The type arguments selects which buffer is returned.
297 	If the requested type is not supported, then 0 is returned. */
298     virtual const double * buffer(tbint_type type = eri) const;
299 
300     /** Given four shell indices, integrals will be computed and placed in
301         the buffer.  The first index corresponds to electron 1 and the
302         second index corresponds to electron 2.*/
303     virtual void compute_shell(int,int) = 0;
304 
305     /** Return log base 2 of the maximum magnitude of any integral in a
306         shell block obtained from compute_shell.  An index of -1 for any
307         argument indicates any shell.  */
308     virtual int log2_shell_bound(int= -1,int= -1) = 0;
309 
310     /** If redundant is true, then keep redundant integrals in the buffer.
311         The default is true. */
redundant()312     int redundant() const { return redundant_; }
313     /// See redundant().
set_redundant(int i)314     void set_redundant(int i) { redundant_ = i; }
315 
316     /// This storage is used to cache computed integrals.
317     virtual void set_integral_storage(size_t storage);
318 
319     /// Return the integral factory that was used to create this object.
integral()320     Integral *integral() const { return integral_; }
321 
322 };
323 
324 // //////////////////////////////////////////////////////////////////////////
325 
326 class ShellQuartetIter {
327   protected:
328     const double * buf;
329     double scale_;
330 
331     int redund_;
332 
333     int e12;
334     int e34;
335     int e13e24;
336 
337     int index;
338 
339     int istart;
340     int jstart;
341     int kstart;
342     int lstart;
343 
344     int iend;
345     int jend;
346     int kend;
347     int lend;
348 
349     int icur;
350     int jcur;
351     int kcur;
352     int lcur;
353 
354     int i_;
355     int j_;
356     int k_;
357     int l_;
358 
359   public:
360     ShellQuartetIter();
361     virtual ~ShellQuartetIter();
362 
363     virtual void init(const double *,
364                       int, int, int, int,
365                       int, int, int, int,
366                       int, int, int, int,
367                       double, int);
368 
369     virtual void start();
370     virtual void next();
371 
ready()372     int ready() const { return icur < iend; }
373 
i()374     int i() const { return i_; }
j()375     int j() const { return j_; }
k()376     int k() const { return k_; }
l()377     int l() const { return l_; }
378 
nint()379     int nint() const { return iend*jend*kend*lend; }
380 
val()381     double val() const { return buf[index]*scale_; }
382 };
383 
384 class TwoBodyIntIter {
385   protected:
386     Ref<TwoBodyInt> tbi;
387     ShellQuartetIter sqi;
388 
389     int iend;
390 
391     int icur;
392     int jcur;
393     int kcur;
394     int lcur;
395 
396   public:
397     TwoBodyIntIter();
398     TwoBodyIntIter(const Ref<TwoBodyInt>&);
399 
400     virtual ~TwoBodyIntIter();
401 
402     virtual void start();
403     virtual void next();
404 
ready()405     int ready() const { return (icur < iend); }
406 
ishell()407     int ishell() const { return icur; }
jshell()408     int jshell() const { return jcur; }
kshell()409     int kshell() const { return kcur; }
lshell()410     int lshell() const { return lcur; }
411 
412     virtual double scale() const;
413 
414     ShellQuartetIter& current_quartet();
415 };
416 
417 // //////////////////////////////////////////////////////////////////////////
418 
419 /** This is an abstract base type for classes that
420     compute integrals involving two electrons.
421  */
422 class TwoBodyDerivInt : public RefCount {
423   protected:
424     // this is who created me
425     Integral *integral_;
426 
427     Ref<GaussianBasisSet> bs1_;
428     Ref<GaussianBasisSet> bs2_;
429     Ref<GaussianBasisSet> bs3_;
430     Ref<GaussianBasisSet> bs4_;
431 
432     double *buffer_;
433 
434     TwoBodyDerivInt(Integral* integral,
435                     const Ref<GaussianBasisSet>&b1,
436                     const Ref<GaussianBasisSet>&b2,
437                     const Ref<GaussianBasisSet>&b3,
438                     const Ref<GaussianBasisSet>&b4);
439   public:
440     virtual ~TwoBodyDerivInt();
441 
442     /// Return the number of basis functions on center one.
443     int nbasis() const;
444 
445     /// Return the number of basis functions on center one.
446     int nbasis1() const;
447     /// Return the number of basis functions on center two.
448     int nbasis2() const;
449     /// Return the number of basis functions on center three.
450     int nbasis3() const;
451     /// Return the number of basis functions on center four.
452     int nbasis4() const;
453 
454     /// Return the number of shells on center one.
455     int nshell() const;
456 
457     /// Return the number of shells on center one.
458     int nshell1() const;
459     /// Return the number of shells on center two.
460     int nshell2() const;
461     /// Return the number of shells on center three.
462     int nshell3() const;
463     /// Return the number of shells on center four.
464     int nshell4() const;
465 
466     /// Return the basis set on center one.
467     Ref<GaussianBasisSet> basis();
468 
469     /// Return the basis set on center one.
470     Ref<GaussianBasisSet> basis1();
471     /// Return the basis set on center two.
472     Ref<GaussianBasisSet> basis2();
473     /// Return the basis set on center three.
474     Ref<GaussianBasisSet> basis3();
475     /// Return the basis set on center four.
476     Ref<GaussianBasisSet> basis4();
477 
478     /** The computed shell integrals will be put in the buffer returned
479         by this member.
480     */
481     const double * buffer() const;
482 
483     /** Given for shell indices, this will cause the integral buffer
484         to be filled in. */
485     virtual void compute_shell(int,int,int,int,DerivCenters&) = 0;
486 
487     /** Return log base 2 of the maximum magnitude of any integral in a
488         shell block.  An index of -1 for any argument indicates any shell.  */
489     virtual int log2_shell_bound(int= -1,int= -1,int= -1,int= -1) = 0;
490 };
491 
492 // //////////////////////////////////////////////////////////////////////////
493 
494 /** This is an abstract base type for classes that
495     compute three centers integrals involving two electrons.
496  */
497 class TwoBodyThreeCenterDerivInt : public RefCount {
498   protected:
499     // this is who created me
500     Integral *integral_;
501 
502     Ref<GaussianBasisSet> bs1_;
503     Ref<GaussianBasisSet> bs2_;
504     Ref<GaussianBasisSet> bs3_;
505 
506     double *buffer_;
507 
508     TwoBodyThreeCenterDerivInt(Integral* integral,
509                     const Ref<GaussianBasisSet>&b1,
510                     const Ref<GaussianBasisSet>&b2,
511                     const Ref<GaussianBasisSet>&b3);
512   public:
513     virtual ~TwoBodyThreeCenterDerivInt();
514 
515     /// Return the number of basis functions on center one.
516     int nbasis() const;
517 
518     /// Return the number of basis functions on center one.
519     int nbasis1() const;
520     /// Return the number of basis functions on center two.
521     int nbasis2() const;
522     /// Return the number of basis functions on center three.
523     int nbasis3() const;
524 
525     /// Return the number of shells on center one.
526     int nshell() const;
527 
528     /// Return the number of shells on center one.
529     int nshell1() const;
530     /// Return the number of shells on center two.
531     int nshell2() const;
532     /// Return the number of shells on center three.
533     int nshell3() const;
534 
535     /// Return the basis set on center one.
536     Ref<GaussianBasisSet> basis();
537 
538     /// Return the basis set on center one.
539     Ref<GaussianBasisSet> basis1();
540     /// Return the basis set on center two.
541     Ref<GaussianBasisSet> basis2();
542     /// Return the basis set on center three.
543     Ref<GaussianBasisSet> basis3();
544 
545     /** The computed shell integrals will be put in the buffer returned
546         by this member.
547     */
548     const double * buffer() const;
549 
550     /** Given for shell indices, this will cause the integral buffer
551         to be filled in. */
552     virtual void compute_shell(int,int,int,DerivCenters&) = 0;
553 
554     /** Return log base 2 of the maximum magnitude of any integral in a
555         shell block.  An index of -1 for any argument indicates any shell.  */
556     virtual int log2_shell_bound(int= -1,int= -1,int= -1) = 0;
557 };
558 
559 // //////////////////////////////////////////////////////////////////////////
560 
561 /** This is an abstract base type for classes that
562     compute two centers integrals involving two electrons.
563  */
564 class TwoBodyTwoCenterDerivInt : public RefCount {
565   protected:
566     // this is who created me
567     Integral *integral_;
568 
569     Ref<GaussianBasisSet> bs1_;
570     Ref<GaussianBasisSet> bs2_;
571 
572     double *buffer_;
573 
574     TwoBodyTwoCenterDerivInt(Integral* integral,
575                     const Ref<GaussianBasisSet>&b1,
576                     const Ref<GaussianBasisSet>&b2);
577   public:
578     virtual ~TwoBodyTwoCenterDerivInt();
579 
580     /// Return the number of basis functions on center one.
581     int nbasis() const;
582 
583     /// Return the number of basis functions on center one.
584     int nbasis1() const;
585     /// Return the number of basis functions on center two.
586     int nbasis2() const;
587 
588     /// Return the number of shells on center one.
589     int nshell() const;
590 
591     /// Return the number of shells on center one.
592     int nshell1() const;
593     /// Return the number of shells on center two.
594     int nshell2() const;
595 
596     /// Return the basis set on center one.
597     Ref<GaussianBasisSet> basis();
598 
599     /// Return the basis set on center one.
600     Ref<GaussianBasisSet> basis1();
601     /// Return the basis set on center two.
602     Ref<GaussianBasisSet> basis2();
603 
604     /** The computed shell integrals will be put in the buffer returned
605         by this member.
606     */
607     const double * buffer() const;
608 
609     /** Given for shell indices, this will cause the integral buffer
610         to be filled in. */
611     virtual void compute_shell(int,int,DerivCenters&) = 0;
612 
613     /** Return log base 2 of the maximum magnitude of any integral in a
614         shell block.  An index of -1 for any argument indicates any shell.  */
615     virtual int log2_shell_bound(int= -1,int= -1) = 0;
616 };
617 
618 }
619 
620 #endif
621 
622 // Local Variables:
623 // mode: c++
624 // c-file-style: "ETS"
625 // End:
626