// // int2e.cc // // Copyright (C) 2004 Sandia National Laboratories. // // Author: Joseph Kenny // Maintainer: Joseph Kenny // // This file is part of the SC Toolkit. // // The SC Toolkit is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // The SC Toolkit is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with the SC Toolkit; see the file COPYING.LIB. If not, write to // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // // The U.S. Government is granted a limited license as per AL 91-7. // #ifdef __GNUG__ #pragma implementation #endif #include #include #include using namespace std; using namespace sc; using namespace MPQC; using namespace Chemistry; using namespace Chemistry::QC::GaussianBasis; Int2eCCA::Int2eCCA(Integral *integral, const Ref&b1, const Ref&b2, const Ref&b3, const Ref&b4, int order, size_t storage, IntegralEvaluatorFactory eval_factory, bool use_opaque, string eval_type ): bs1_(b1), bs2_(b2), bs3_(b3), bs4_(b4), erep_ptr_(0), integral_(integral), eval_factory_(eval_factory), use_opaque_(use_opaque), buffer_(0) { /* Allocate storage for the integral buffer. */ int maxsize = bs1_->max_ncartesian_in_shell() *bs2_->max_ncartesian_in_shell() *bs3_->max_ncartesian_in_shell() *bs4_->max_ncartesian_in_shell(); if( order == 1 ) maxsize *= 9; else if( order != 0 ) throw FeatureNotImplemented("only first order derivatives are available", __FILE__,__LINE__); if( !use_opaque ) buffer_ = new double[maxsize]; cca_bs1_ = GaussianBasis_Molecular::_create(); cca_bs2_ = GaussianBasis_Molecular::_create(); cca_bs3_ = GaussianBasis_Molecular::_create(); cca_bs4_ = GaussianBasis_Molecular::_create(); cca_bs1_.initialize( bs1_.pointer(), bs1_->name() ); cca_bs2_.initialize( bs2_.pointer(), bs2_->name() ); cca_bs3_.initialize( bs3_.pointer(), bs3_->name() ); cca_bs4_.initialize( bs4_.pointer(), bs4_->name() ); cca_dc_ = Chemistry_QC_GaussianBasis_DerivCenters::_create(); if( eval_type == "eri" ) { erep_ = eval_factory_.get_integral_evaluator4( "eri2", 0, cca_bs1_, cca_bs2_, cca_bs3_, cca_bs4_ ); erep_ptr_ = &erep_; if( use_opaque_ ) buffer_ = static_cast( erep_ptr_->get_buffer() ); } else if( eval_type == "eri_1der") { erep_1der_ = eval_factory_.get_integral_evaluator4( "eri2", 1, cca_bs1_, cca_bs2_, cca_bs3_, cca_bs4_ ); erep_1der_ptr_ = &erep_1der_; if( use_opaque_ ) buffer_ = static_cast( erep_1der_ptr_->get_buffer() ); } else { std::cerr << "integral type: " << eval_type << std::endl; throw InputError("unrecognized integral type", __FILE__,__LINE__); } if (!buffer_) throw ProgrammingError("buffer not assigned", __FILE__,__LINE__); } void Int2eCCA::compute_erep( int is, int js, int ks, int ls ) { cca_dc_.clear(); if( use_opaque_ ) erep_ptr_->compute( is, js, ks, ls, 0, cca_dc_ ); else { sidl_buffer_ = erep_ptr_->compute_array( is, js, ks, ls, 0, cca_dc_ ); int nelem = bs1_->shell(is).nfunction() * bs2_->shell(js).nfunction() * bs3_->shell(ks).nfunction() * bs4_->shell(ls).nfunction(); copy_buffer(nelem); } if(!redundant_) { remove_redundant(is,js,ks,ls); } } void Int2eCCA::compute_erep_1der( int is, int js, int ks, int ls, Chemistry::QC::GaussianBasis::DerivCenters &dc ) { if( use_opaque_ ) erep_1der_ptr_->compute( is, js, ks, ls, 1, dc ); else { sidl_buffer_ = erep_ptr_->compute_array( is, js, ks, ls, 1, dc ); int nelem = bs1_->shell(is).nfunction() * bs2_->shell(js).nfunction() * bs3_->shell(ks).nfunction() * bs4_->shell(ls).nfunction(); copy_buffer(nelem); } if(!redundant_) { remove_redundant(is,js,ks,ls); } } void Int2eCCA::copy_buffer( int n ) { for( int i=0; infunction(); int nbf2 = int_shell2->nfunction(); int nbf3 = int_shell3->nfunction(); int nbf4 = int_shell4->nfunction(); double *redundant_ptr = source; double *nonredundant_ptr = target; int nbf34 = nbf3*nbf4; for (i=0; ishell(sh1)); GaussianShell* int_shell2(&bs2_->shell(sh2)); GaussianShell* int_shell3(&bs3_->shell(sh3)); GaussianShell* int_shell4(&bs4_->shell(sh4)); bool need_unique_ints_only = false; int e12,e34,e13e24; e12 = 0; if (int_shell1 == int_shell2 && int_shell1->nfunction()>1) e12 = 1; e34 = 0; if (int_shell3 == int_shell4 && int_shell3->nfunction()>1) e34 = 1; e13e24 = 0; if (int_shell1 == int_shell3 && int_shell2 == int_shell4 && int_shell1->nfunction()*int_shell2->nfunction()>1) e13e24 = 1; if ( e12 || e34 || e13e24 ) need_unique_ints_only = true; if (need_unique_ints_only) { std::cout.flush(); get_nonredundant_ints_( buffer_, buffer_, e13e24, e12, e34, int_shell1, int_shell2, int_shell3, int_shell4 ); } } #else ///////////////////////////////////////////////////////////////////////////// // Code for removing redundant integrals // copied liberally from intV3 static int shell_offset(Ref cs, int off) { return off + cs->nshell(); } #define INT_MAX1(n1) ((n1)-1) #define INT_MAX2(e12,i,n2) ((e12)?(i):((n2)-1)) #define INT_MAX3(e13e24,i,n3) ((e13e24)?(i):((n3)-1)) #define INT_MAX4(e13e24,e34,i,j,k,n4) \ ((e34)?(((e13e24)&&((k)==(i)))?(j):(k)) \ :((e13e24)&&((k)==(i)))?(j):(n4)-1) void nonredundant_erep(double *buffer, int e12, int e34, int e13e24, int n1, int n2, int n3, int n4, int *red_off, int *nonred_off) { int nonredundant_index; int i,j,k,l; double *redundant_ptr = &buffer[*red_off]; double *nonredundant_ptr = &buffer[*nonred_off]; nonredundant_index = 0; int n34 = n3*n4; for (i=0; ishell(sh1); GaussianShell* int_shell2; if (!int_unit2) int_shell2 = &bs2_->shell(sh2); else int_shell2 = int_unit_shell; GaussianShell* int_shell3 = &bs3_->shell(sh3); GaussianShell* int_shell4; if (!int_unit4) int_shell4 = &bs4_->shell(sh4); else int_shell4 = int_unit_shell; int redundant_offset = 0; int nonredundant_offset = 0; if ((osh1 == osh4)&&(osh2 == osh3)&&(osh1 != osh2)) { throw ProgrammingError("nonredundant integrals cannot be generated", __FILE__,__LINE__); } int e12 = (int_unit2?0:(osh1 == osh2)); int e13e24 = ((osh1 == osh3) && ((int_unit2 && int_unit4) || ((int_unit2||int_unit4)?0:(osh2 == osh4)))); int e34 = (int_unit4?0:(osh3 == osh4)); if (e12||e34||e13e24) { nonredundant_erep(buffer_,e12,e34,e13e24, int_shell1->nfunction(), int_shell2->nfunction(), int_shell3->nfunction(), int_shell4->nfunction(), &redundant_offset, &nonredundant_offset); } } #endif ///////////////////////////////////////////////////////////////////////////// // Local Variables: // mode: c++ // End: