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