1 | //
|
---|
2 | // int2e.cc
|
---|
3 | //
|
---|
4 | // Copyright (C) 2004 Sandia National Laboratories.
|
---|
5 | //
|
---|
6 | // Author: Joseph Kenny <jpkenny@sandia.gov>
|
---|
7 | // Maintainer: Joseph Kenny
|
---|
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 | #ifdef __GNUG__
|
---|
29 | #pragma implementation
|
---|
30 | #endif
|
---|
31 |
|
---|
32 | #include <chemistry/qc/intcca/int2e.h>
|
---|
33 | #include <Chemistry_Chemistry_QC_GaussianBasis_DerivCenters.hh>
|
---|
34 | #include <util/class/scexception.h>
|
---|
35 |
|
---|
36 | using namespace std;
|
---|
37 | using namespace sc;
|
---|
38 | using namespace MPQC;
|
---|
39 | using namespace Chemistry;
|
---|
40 | using namespace Chemistry::QC::GaussianBasis;
|
---|
41 |
|
---|
42 | Int2eCCA::Int2eCCA(Integral *integral,
|
---|
43 | const Ref<GaussianBasisSet>&b1,
|
---|
44 | const Ref<GaussianBasisSet>&b2,
|
---|
45 | const Ref<GaussianBasisSet>&b3,
|
---|
46 | const Ref<GaussianBasisSet>&b4,
|
---|
47 | int order, size_t storage,
|
---|
48 | IntegralEvaluatorFactory eval_factory,
|
---|
49 | bool use_opaque, string eval_type ):
|
---|
50 | bs1_(b1), bs2_(b2), bs3_(b3), bs4_(b4),
|
---|
51 | erep_ptr_(0), integral_(integral), eval_factory_(eval_factory),
|
---|
52 | use_opaque_(use_opaque), buffer_(0)
|
---|
53 | {
|
---|
54 |
|
---|
55 | /* Allocate storage for the integral buffer. */
|
---|
56 | int maxsize = bs1_->max_ncartesian_in_shell()
|
---|
57 | *bs2_->max_ncartesian_in_shell()
|
---|
58 | *bs3_->max_ncartesian_in_shell()
|
---|
59 | *bs4_->max_ncartesian_in_shell();
|
---|
60 | if( order == 1 )
|
---|
61 | maxsize *= 9;
|
---|
62 | else if( order != 0 )
|
---|
63 | throw FeatureNotImplemented("only first order derivatives are available",
|
---|
64 | __FILE__,__LINE__);
|
---|
65 | if( !use_opaque ) buffer_ = new double[maxsize];
|
---|
66 |
|
---|
67 | cca_bs1_ = GaussianBasis_Molecular::_create();
|
---|
68 | cca_bs2_ = GaussianBasis_Molecular::_create();
|
---|
69 | cca_bs3_ = GaussianBasis_Molecular::_create();
|
---|
70 | cca_bs4_ = GaussianBasis_Molecular::_create();
|
---|
71 | cca_bs1_.initialize( bs1_.pointer(), bs1_->name() );
|
---|
72 | cca_bs2_.initialize( bs2_.pointer(), bs2_->name() );
|
---|
73 | cca_bs3_.initialize( bs3_.pointer(), bs3_->name() );
|
---|
74 | cca_bs4_.initialize( bs4_.pointer(), bs4_->name() );
|
---|
75 |
|
---|
76 | cca_dc_ = Chemistry_QC_GaussianBasis_DerivCenters::_create();
|
---|
77 |
|
---|
78 | if( eval_type == "eri" ) {
|
---|
79 | erep_ = eval_factory_.get_integral_evaluator4( "eri2", 0,
|
---|
80 | cca_bs1_, cca_bs2_,
|
---|
81 | cca_bs3_, cca_bs4_ );
|
---|
82 | erep_ptr_ = &erep_;
|
---|
83 | if( use_opaque_ )
|
---|
84 | buffer_ = static_cast<double*>( erep_ptr_->get_buffer() );
|
---|
85 | }
|
---|
86 | else if( eval_type == "eri_1der") {
|
---|
87 | erep_1der_ = eval_factory_.get_integral_evaluator4( "eri2", 1,
|
---|
88 | cca_bs1_, cca_bs2_,
|
---|
89 | cca_bs3_, cca_bs4_ );
|
---|
90 | erep_1der_ptr_ = &erep_1der_;
|
---|
91 | if( use_opaque_ )
|
---|
92 | buffer_ = static_cast<double*>( erep_1der_ptr_->get_buffer() );
|
---|
93 | }
|
---|
94 | else {
|
---|
95 | std::cerr << "integral type: " << eval_type << std::endl;
|
---|
96 | throw InputError("unrecognized integral type",
|
---|
97 | __FILE__,__LINE__);
|
---|
98 | }
|
---|
99 | if (!buffer_)
|
---|
100 | throw ProgrammingError("buffer not assigned",
|
---|
101 | __FILE__,__LINE__);
|
---|
102 | }
|
---|
103 |
|
---|
104 | void
|
---|
105 | Int2eCCA::compute_erep( int is, int js, int ks, int ls )
|
---|
106 | {
|
---|
107 | cca_dc_.clear();
|
---|
108 | if( use_opaque_ )
|
---|
109 | erep_ptr_->compute( is, js, ks, ls, 0, cca_dc_ );
|
---|
110 | else {
|
---|
111 | sidl_buffer_ = erep_ptr_->compute_array( is, js, ks, ls, 0, cca_dc_ );
|
---|
112 | int nelem = bs1_->shell(is).nfunction() * bs2_->shell(js).nfunction() *
|
---|
113 | bs3_->shell(ks).nfunction() * bs4_->shell(ls).nfunction();
|
---|
114 | copy_buffer(nelem);
|
---|
115 | }
|
---|
116 |
|
---|
117 | if(!redundant_) {
|
---|
118 | remove_redundant(is,js,ks,ls);
|
---|
119 | }
|
---|
120 | }
|
---|
121 |
|
---|
122 | void
|
---|
123 | Int2eCCA::compute_erep_1der( int is, int js, int ks, int ls,
|
---|
124 | Chemistry::QC::GaussianBasis::DerivCenters &dc )
|
---|
125 | {
|
---|
126 |
|
---|
127 | if( use_opaque_ )
|
---|
128 | erep_1der_ptr_->compute( is, js, ks, ls, 1, dc );
|
---|
129 | else {
|
---|
130 | sidl_buffer_ = erep_ptr_->compute_array( is, js, ks, ls, 1, dc );
|
---|
131 | int nelem = bs1_->shell(is).nfunction() * bs2_->shell(js).nfunction() *
|
---|
132 | bs3_->shell(ks).nfunction() * bs4_->shell(ls).nfunction();
|
---|
133 | copy_buffer(nelem);
|
---|
134 | }
|
---|
135 |
|
---|
136 | if(!redundant_) {
|
---|
137 | remove_redundant(is,js,ks,ls);
|
---|
138 | }
|
---|
139 | }
|
---|
140 |
|
---|
141 | void
|
---|
142 | Int2eCCA::copy_buffer( int n )
|
---|
143 | {
|
---|
144 | for( int i=0; i<n; ++i)
|
---|
145 | buffer_[i] = sidl_buffer_.get(i);
|
---|
146 | }
|
---|
147 |
|
---|
148 | #ifndef INTV3_ORDER
|
---|
149 |
|
---|
150 | /////////////////////////////////////////////////////////////////////////////
|
---|
151 | // Code for removing redundant integrals
|
---|
152 | // copied liberally from cints
|
---|
153 |
|
---|
154 | void get_nonredundant_ints_(double *source, double *target,
|
---|
155 | int e13e24, int e12, int e34,
|
---|
156 | GaussianShell* int_shell1,GaussianShell* int_shell2,
|
---|
157 | GaussianShell* int_shell3,GaussianShell* int_shell4)
|
---|
158 | {
|
---|
159 |
|
---|
160 | //std::cout << "\nremoving redundant integrals";
|
---|
161 |
|
---|
162 | int i,j,k,l;
|
---|
163 |
|
---|
164 | int nbf1 = int_shell1->nfunction();
|
---|
165 | int nbf2 = int_shell2->nfunction();
|
---|
166 | int nbf3 = int_shell3->nfunction();
|
---|
167 | int nbf4 = int_shell4->nfunction();
|
---|
168 |
|
---|
169 | double *redundant_ptr = source;
|
---|
170 | double *nonredundant_ptr = target;
|
---|
171 |
|
---|
172 | int nbf34 = nbf3*nbf4;
|
---|
173 | for (i=0; i<nbf1; i++) {
|
---|
174 | int jmax = e12 ? i : nbf2-1;
|
---|
175 | for (j=0; j<=jmax; j++) {
|
---|
176 | int kmax = e13e24 ? i : nbf3-1;
|
---|
177 | for (k=0; k<=kmax; k++) {
|
---|
178 | int lmax = e34 ? ( (e13e24&&(i==k)) ? j : k) :
|
---|
179 | ( (e13e24&&(i==k)) ? j : nbf4-1);
|
---|
180 | for (l=0; l<=lmax; l++) {
|
---|
181 | *(nonredundant_ptr++) = redundant_ptr[l];
|
---|
182 | }
|
---|
183 | redundant_ptr += nbf4;
|
---|
184 | }
|
---|
185 | redundant_ptr += (nbf3-(kmax+1))*nbf4;
|
---|
186 | }
|
---|
187 | redundant_ptr += (nbf2-(jmax+1))*nbf34;
|
---|
188 | }
|
---|
189 | }
|
---|
190 |
|
---|
191 | void
|
---|
192 | Int2eCCA::remove_redundant(int sh1, int sh2, int sh3, int sh4) {
|
---|
193 |
|
---|
194 | GaussianShell* int_shell1(&bs1_->shell(sh1));
|
---|
195 | GaussianShell* int_shell2(&bs2_->shell(sh2));
|
---|
196 | GaussianShell* int_shell3(&bs3_->shell(sh3));
|
---|
197 | GaussianShell* int_shell4(&bs4_->shell(sh4));
|
---|
198 |
|
---|
199 | bool need_unique_ints_only = false;
|
---|
200 | int e12,e34,e13e24;
|
---|
201 | e12 = 0;
|
---|
202 | if (int_shell1 == int_shell2 && int_shell1->nfunction()>1)
|
---|
203 | e12 = 1;
|
---|
204 | e34 = 0;
|
---|
205 | if (int_shell3 == int_shell4 && int_shell3->nfunction()>1)
|
---|
206 | e34 = 1;
|
---|
207 | e13e24 = 0;
|
---|
208 | if (int_shell1 == int_shell3 && int_shell2 ==
|
---|
209 | int_shell4 && int_shell1->nfunction()*int_shell2->nfunction()>1)
|
---|
210 | e13e24 = 1;
|
---|
211 |
|
---|
212 | if ( e12 || e34 || e13e24 )
|
---|
213 | need_unique_ints_only = true;
|
---|
214 |
|
---|
215 | if (need_unique_ints_only) {
|
---|
216 | std::cout.flush();
|
---|
217 | get_nonredundant_ints_( buffer_, buffer_, e13e24, e12, e34,
|
---|
218 | int_shell1, int_shell2, int_shell3, int_shell4 );
|
---|
219 | }
|
---|
220 | }
|
---|
221 |
|
---|
222 | #else
|
---|
223 |
|
---|
224 | /////////////////////////////////////////////////////////////////////////////
|
---|
225 | // Code for removing redundant integrals
|
---|
226 | // copied liberally from intV3
|
---|
227 |
|
---|
228 | static int
|
---|
229 | shell_offset(Ref<GaussianBasisSet> cs, int off)
|
---|
230 | {
|
---|
231 | return off + cs->nshell();
|
---|
232 | }
|
---|
233 |
|
---|
234 | #define INT_MAX1(n1) ((n1)-1)
|
---|
235 | #define INT_MAX2(e12,i,n2) ((e12)?(i):((n2)-1))
|
---|
236 | #define INT_MAX3(e13e24,i,n3) ((e13e24)?(i):((n3)-1))
|
---|
237 | #define INT_MAX4(e13e24,e34,i,j,k,n4) \
|
---|
238 | ((e34)?(((e13e24)&&((k)==(i)))?(j):(k)) \
|
---|
239 | :((e13e24)&&((k)==(i)))?(j):(n4)-1)
|
---|
240 |
|
---|
241 | void
|
---|
242 | nonredundant_erep(double *buffer, int e12, int e34, int e13e24,
|
---|
243 | int n1, int n2, int n3, int n4,
|
---|
244 | int *red_off, int *nonred_off)
|
---|
245 | {
|
---|
246 | int nonredundant_index;
|
---|
247 | int i,j,k,l;
|
---|
248 |
|
---|
249 | double *redundant_ptr = &buffer[*red_off];
|
---|
250 | double *nonredundant_ptr = &buffer[*nonred_off];
|
---|
251 |
|
---|
252 | nonredundant_index = 0;
|
---|
253 | int n34 = n3*n4;
|
---|
254 | for (i=0; i<n1; i++) {
|
---|
255 | int jmax = INT_MAX2(e12,i,n2);
|
---|
256 | for (j=0; j<=jmax; j++) {
|
---|
257 | int kmax = INT_MAX3(e13e24,i,n3);
|
---|
258 | for (k=0; k<=kmax; k++) {
|
---|
259 | int lmax = INT_MAX4(e13e24,e34,i,j,k,n4);
|
---|
260 | for (l=0; l<=lmax; l++) {
|
---|
261 | nonredundant_ptr[l] = redundant_ptr[l];
|
---|
262 | }
|
---|
263 | redundant_ptr += n4;
|
---|
264 | nonredundant_index += lmax+1;
|
---|
265 | nonredundant_ptr += lmax+1;
|
---|
266 | }
|
---|
267 | redundant_ptr += (n3-(kmax+1))*n4;
|
---|
268 | }
|
---|
269 | redundant_ptr += (n2-(jmax+1))*n34;
|
---|
270 | }
|
---|
271 | *red_off += n1*n2*n34;
|
---|
272 | *nonred_off += nonredundant_index;
|
---|
273 | }
|
---|
274 |
|
---|
275 | void
|
---|
276 | Int2eCCA::remove_redundant(int is, int js, int ks, int ls) {
|
---|
277 |
|
---|
278 | int bs1_shell_offset = 0;
|
---|
279 | int bs2_shell_offset, bs3_shell_offset, bs4_shell_offset;
|
---|
280 |
|
---|
281 | int shell_offset1 = shell_offset(bs1_,0);
|
---|
282 | int shell_offset2, shell_offset3, shell_offset4;
|
---|
283 | if (bs2_ == bs1_) {
|
---|
284 | shell_offset2 = shell_offset1;
|
---|
285 | bs2_shell_offset = bs1_shell_offset;
|
---|
286 | }
|
---|
287 | else {
|
---|
288 | shell_offset2 = shell_offset(bs2_,shell_offset1);
|
---|
289 | bs2_shell_offset = shell_offset1;
|
---|
290 | }
|
---|
291 |
|
---|
292 | if (bs3_ == bs1_) {
|
---|
293 | shell_offset3 = shell_offset2;
|
---|
294 | bs3_shell_offset = bs1_shell_offset;
|
---|
295 | }
|
---|
296 | else if (bs3_ == bs2_) {
|
---|
297 | shell_offset3 = shell_offset2;
|
---|
298 | bs3_shell_offset = bs2_shell_offset;
|
---|
299 | }
|
---|
300 | else {
|
---|
301 | shell_offset3 = shell_offset(bs3_,shell_offset2);
|
---|
302 | bs3_shell_offset = shell_offset2;
|
---|
303 | }
|
---|
304 |
|
---|
305 | if (bs4_ == bs1_) {
|
---|
306 | bs4_shell_offset = bs1_shell_offset;
|
---|
307 | }
|
---|
308 | else if (bs4_ == bs2_) {
|
---|
309 | bs4_shell_offset = bs2_shell_offset;
|
---|
310 | }
|
---|
311 | else if (bs4_ == bs3_) {
|
---|
312 | bs4_shell_offset = bs3_shell_offset;
|
---|
313 | }
|
---|
314 | else {
|
---|
315 | bs4_shell_offset = shell_offset3;
|
---|
316 | }
|
---|
317 |
|
---|
318 | int int_unit2 = 0;
|
---|
319 | int int_unit4 = 0;
|
---|
320 | int osh1 = is + bs1_shell_offset;
|
---|
321 | int osh2;
|
---|
322 | if (!int_unit2) osh2 = js + bs2_shell_offset;
|
---|
323 | int osh3 = ks + bs3_shell_offset;
|
---|
324 | int osh4;
|
---|
325 | if (!int_unit4) osh4 = ls + bs4_shell_offset;
|
---|
326 |
|
---|
327 | int sh1 = is;
|
---|
328 | int sh2;
|
---|
329 | if (!int_unit2) sh2 = js;
|
---|
330 | int sh3 = ks;
|
---|
331 | int sh4;
|
---|
332 | if (!int_unit4) sh4 = ls;
|
---|
333 |
|
---|
334 | GaussianShell* int_unit_shell = 0;
|
---|
335 | GaussianShell* int_shell1 = &bs1_->shell(sh1);
|
---|
336 | GaussianShell* int_shell2;
|
---|
337 | if (!int_unit2) int_shell2 = &bs2_->shell(sh2);
|
---|
338 | else int_shell2 = int_unit_shell;
|
---|
339 | GaussianShell* int_shell3 = &bs3_->shell(sh3);
|
---|
340 | GaussianShell* int_shell4;
|
---|
341 | if (!int_unit4) int_shell4 = &bs4_->shell(sh4);
|
---|
342 | else int_shell4 = int_unit_shell;
|
---|
343 |
|
---|
344 | int redundant_offset = 0;
|
---|
345 | int nonredundant_offset = 0;
|
---|
346 |
|
---|
347 | if ((osh1 == osh4)&&(osh2 == osh3)&&(osh1 != osh2)) {
|
---|
348 | throw ProgrammingError("nonredundant integrals cannot be generated",
|
---|
349 | __FILE__,__LINE__);
|
---|
350 | }
|
---|
351 |
|
---|
352 | int e12 = (int_unit2?0:(osh1 == osh2));
|
---|
353 | int e13e24 = ((osh1 == osh3)
|
---|
354 | && ((int_unit2 && int_unit4)
|
---|
355 | || ((int_unit2||int_unit4)?0:(osh2 == osh4))));
|
---|
356 | int e34 = (int_unit4?0:(osh3 == osh4));
|
---|
357 | if (e12||e34||e13e24) {
|
---|
358 | nonredundant_erep(buffer_,e12,e34,e13e24,
|
---|
359 | int_shell1->nfunction(),
|
---|
360 | int_shell2->nfunction(),
|
---|
361 | int_shell3->nfunction(),
|
---|
362 | int_shell4->nfunction(),
|
---|
363 | &redundant_offset,
|
---|
364 | &nonredundant_offset);
|
---|
365 | }
|
---|
366 | }
|
---|
367 |
|
---|
368 | #endif
|
---|
369 |
|
---|
370 | /////////////////////////////////////////////////////////////////////////////
|
---|
371 |
|
---|
372 | // Local Variables:
|
---|
373 | // mode: c++
|
---|
374 | // End:
|
---|