source: ThirdParty/mpqc_open/src/lib/chemistry/cca/MPQC_IntegralEvaluator2_Impl.cc@ 7516f6

Action_Thermostats Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.1 ChemicalSpaceEvaluator Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Exclude_Hydrogens_annealWithBondGraph Fix_Verbose_Codepatterns ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion Gui_displays_atomic_force_velocity JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool PythonUI_with_named_parameters Recreated_GuiChecks StoppableMakroAction TremoloParser_IncreasedPrecision
Last change on this file since 7516f6 was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100644
File size: 14.0 KB
Line 
1//
2// File: MPQC_IntegralEvaluator2_Impl.cc
3// Symbol: MPQC.IntegralEvaluator2-v0.2
4// Symbol Type: class
5// Babel Version: 0.10.2
6// Description: Server-side implementation for MPQC.IntegralEvaluator2
7//
8// WARNING: Automatically generated; only changes within splicers preserved
9//
10// babel-version = 0.10.2
11//
12#include "MPQC_IntegralEvaluator2_Impl.hh"
13
14// DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2._includes)
15#include <iostream>
16#include <sstream>
17#include <util/class/scexception.h>
18#pragma implementation "ccaiter.h"
19#include <ccaiter.h>
20
21using namespace std;
22using namespace Chemistry::QC::GaussianBasis;
23
24Ref<GaussianBasisSet> basis_cca_to_sc(Molecular&);
25
26// DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2._includes)
27
28// user-defined constructor.
29void MPQC::IntegralEvaluator2_impl::_ctor() {
30 // DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2._ctor)
31 deriv_level_ = -1;
32 // DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2._ctor)
33}
34
35// user-defined destructor.
36void MPQC::IntegralEvaluator2_impl::_dtor() {
37 // DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2._dtor)
38#ifndef INTV3_ORDER
39 if( package_ == "intv3") {
40 delete temp_buffer_;
41 for( int i=0; i<=maxam_; ++i)
42 delete [] reorder_[i];
43 delete [] reorder_;
44 }
45#endif
46 // DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2._dtor)
47}
48
49// static class initializer.
50void MPQC::IntegralEvaluator2_impl::_load() {
51 // DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2._load)
52 // guaranteed to be called at most once before any other method in this class
53 // DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2._load)
54}
55
56// user-defined static methods: (none)
57
58// user-defined non-static methods:
59/**
60 * Method: set_integral_package[]
61 */
62void
63MPQC::IntegralEvaluator2_impl::set_integral_package (
64 /* in */ const ::std::string& label )
65throw ()
66{
67 // DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2.set_integral_package)
68 package_ = label;
69 // DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2.set_integral_package)
70}
71
72/**
73 * Initialize the evaluator.
74 * @param bs1 Molecular basis on center 1.
75 * @param bs2 Molecular basis on center 2.
76 * @param label String specifying integral type.
77 * @param max_deriv Max derivative to compute.
78 */
79void
80MPQC::IntegralEvaluator2_impl::initialize (
81 /* in */ ::Chemistry::QC::GaussianBasis::Molecular bs1,
82 /* in */ ::Chemistry::QC::GaussianBasis::Molecular bs2,
83 /* in */ const ::std::string& label,
84 /* in */ int64_t max_deriv )
85throw ()
86{
87 // DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2.initialize)
88
89 evaluator_label_ = label;
90
91 bs1_ = basis_cca_to_sc( bs1 );
92 if( bs1.isSame(bs2) )
93 bs2_.assign_pointer( bs1_.pointer() );
94 else
95 bs2_ = basis_cca_to_sc( bs2 );
96 max_nshell2_ = bs1_->max_ncartesian_in_shell() *
97 bs2_->max_ncartesian_in_shell();
98 maxam_ = max( bs1_->max_angular_momentum(), bs2_->max_angular_momentum() );
99
100 std::string is_deriv("");
101 if(max_deriv > 0) is_deriv = " derivative";
102 std::cout << " initializing " << package_ << " " << evaluator_label_
103 << is_deriv << " integral evaluator\n";
104 if ( package_ == "intv3" ) {
105 integral_ = new IntegralV3( bs1_, bs2_ );
106 }
107#ifdef HAVE_CINTS
108 else if ( package_ == "cints" )
109 integral_ = new IntegralCints( bs1_, bs2_ );
110#endif
111 else {
112 throw InputError("bad integral package name",
113 __FILE__,__LINE__);
114 }
115
116 int error = 0;
117 if(evaluator_label_ == "overlap")
118 switch( max_deriv ) {
119 case 0:
120 { eval_ = integral_->overlap(); break; }
121 case 1:
122 { deriv_eval_ = integral_->overlap_deriv(); break; }
123 default:
124 ++error;
125 }
126
127 else if(evaluator_label_ == "kinetic")
128 switch( max_deriv ) {
129 case 0:
130 { eval_ = integral_->kinetic(); break; }
131 case 1:
132 { deriv_eval_ = integral_->kinetic_deriv(); break; }
133 default:
134 ++error;
135 }
136
137 else if(evaluator_label_ == "potential")
138 switch( max_deriv ) {
139 case 0:
140 { eval_ = integral_->nuclear(); break; }
141 case 1:
142 { deriv_eval_ = integral_->nuclear_deriv(); break; }
143 default:
144 ++error;
145 }
146
147 else if(evaluator_label_ == "1eham")
148 switch( max_deriv ) {
149 case 0:
150 { eval_ = integral_->hcore(); break; }
151 case 1:
152 { deriv_eval_ = integral_->hcore_deriv(); break; }
153 default:
154 ++error;
155 }
156
157 else
158 throw InputError("unrecognized integral type",
159 __FILE__,__LINE__);
160
161 if( error ) {
162 throw InputError("derivative level not supported",
163 __FILE__,__LINE__);
164 }
165
166 if( eval_.nonnull() ) {
167 int_type_ = one_body;
168 sc_buffer_ = eval_->buffer();
169 }
170 else if( deriv_eval_.nonnull() ) {
171 int_type_ = one_body_deriv;
172 sc_buffer_ = deriv_eval_->buffer();
173 }
174 else
175 throw ProgrammingError("bad pointer to sc integal evaluator",
176 __FILE__,__LINE__);
177 if( !sc_buffer_ )
178 throw ProgrammingError("buffer not assigned",
179 __FILE__,__LINE__);
180 // get a non-const pointer we can write to
181 buf_ = const_cast<double*>( sc_buffer_ );
182
183 if ( package_ == "intv3" ) {
184#ifndef INTV3_ORDER
185 initialize_reorder_intv3();
186#endif
187 }
188
189
190 // DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2.initialize)
191}
192
193/**
194 * Get the buffer pointer
195 * @return Buffer pointer
196 */
197void*
198MPQC::IntegralEvaluator2_impl::get_buffer ()
199throw ()
200
201{
202 // DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2.get_buffer)
203 return const_cast<double*>( sc_buffer_ );
204 // DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2.get_buffer)
205}
206
207/**
208 * Allows a DerivCenters object to be passed to
209 * an evaluator, so that derivatives can be taken
210 * with respect to a specified atom (needed for
211 * derivatives with non-Hellman-Feynman contributions).
212 */
213void
214MPQC::IntegralEvaluator2_impl::set_derivcenters (
215 /* in */ ::Chemistry::QC::GaussianBasis::DerivCenters dc )
216throw ()
217{
218 // DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2.set_derivcenters)
219 deriv_centers_ = dc;
220 // DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2.set_derivcenters)
221}
222
223/**
224 * Compute a shell doublet of integrals.
225 * @param shellnum1 Gaussian shell number 1.
226 * @param shellnum2 Gaussian shell number 2.
227 * @param deriv_level Derivative level.
228 * @param deriv_ctr Derivative center descriptor.
229 */
230void
231MPQC::IntegralEvaluator2_impl::compute (
232 /* in */ int64_t shellnum1,
233 /* in */ int64_t shellnum2,
234 /* in */ int64_t deriv_level,
235 /* in */ ::Chemistry::QC::GaussianBasis::DerivCenters deriv_ctr )
236throw ()
237{
238 // DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2.compute)
239
240 if( int_type_ == one_body )
241 eval_->compute_shell( shellnum1, shellnum2 );
242 else if( int_type_ == one_body_deriv ) {
243 sc::DerivCenters dc;
244
245 if(deriv_ctr.has_omitted_center() && deriv_ctr.omitted_center() == 0 ) {
246 dc.add_omitted(0,deriv_ctr.atom(0));
247 std::cerr << "omitting center 0, atom " << deriv_ctr.omitted_atom() << std::endl;
248 }
249 else {
250 dc.add_center(0,deriv_ctr.atom(0));
251 std::cerr << "doing center 0, atom " << deriv_ctr.atom(0) << std::endl;
252 }
253
254 if(deriv_ctr.has_omitted_center() && deriv_ctr.omitted_center() == 1 ) {
255 dc.add_omitted(1,deriv_ctr.atom(1));
256 std::cerr << "omitting center 1, atom " << deriv_ctr.omitted_atom() << std::endl;
257 }
258 else {
259 dc.add_center(1,deriv_ctr.atom(1));
260 std::cerr << "doing center 1, atom " << deriv_ctr.atom(1) << std::endl;
261 }
262
263 deriv_eval_->compute_shell( shellnum1, shellnum2, dc );
264 }
265 else
266 throw ProgrammingError("bad evaluator type",
267 __FILE__,__LINE__);
268
269 sc::GaussianShell* s1 = &( bs1_->shell(shellnum1) );
270 sc::GaussianShell* s2 = &( bs2_->shell(shellnum2) );
271 int nfunc = s1->nfunction() * s2->nfunction();
272
273 if( int_type_ == one_body_deriv ) {
274 std::cerr << "buffer for shell doublet:\n";
275 std::cerr << "shellnum1: " << shellnum1 << std::endl;
276 int nc1 = s1->ncontraction();
277 for (int i=0; i<nc1; ++i)
278 std::cerr << "am: " << s1->am(i) << std::endl;
279 std::cerr << "shellnum2: " << shellnum2 << std::endl;
280 int nc2 = s2->ncontraction();
281 for (int i=0; i<nc2; ++i)
282 std::cerr << "am: " << s2->am(i) << std::endl;
283
284 std::cerr << "dx\n";
285 for( int i=0; i<nfunc; ++i)
286 std::cerr << sc_buffer_[i] << std::endl;
287 std::cerr << "dy\n";
288 for( int i=nfunc; i<nfunc*2; ++i)
289 std::cerr << sc_buffer_[i] << std::endl;
290 std::cerr << "dz\n";
291 for( int i=nfunc*2; i<nfunc*3; ++i)
292 std::cerr << sc_buffer_[i] << std::endl;
293 }
294
295#ifndef INTV3_ORDER
296 if( package_ == "intv3") reorder_intv3( shellnum1, shellnum2 );
297#endif
298
299 // debug
300 //if( int_type_ == one_body_deriv ) {
301 // std::cerr << "buffer for shell doublet (after reorder): " << shellnum1 << " " << shellnum2 << std::endl;
302 // std::cerr << "dx\n";
303 // for( int i=0; i<nfunc; ++i)
304 // std::cerr << sc_buffer_[i] << std::endl;
305 // std::cerr << "dy\n";
306 // for( int i=nfunc; i<nfunc*2; ++i)
307 // std::cerr << sc_buffer_[i] << std::endl;
308 // std::cerr << "dz\n";
309 // for( int i=nfunc*2; i<nfunc*3; ++i)
310 // std::cerr << sc_buffer_[i] << std::endl;
311 //}
312
313 // debug
314 //sc::GaussianShell &s1 = bs1_->shell(shellnum1);
315 //sc::GaussianShell &s2 = bs2_->shell(shellnum2);
316 //int nfunc = s1.nfunction() * s2.nfunction();
317 //cout << "buffer " << shellnum1 << " " << shellnum2 << endl;
318 //for( int i=0; i<nfunc; ++i)
319 // cout << sc_buffer_[i] << endl;
320
321 // DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2.compute)
322}
323
324/**
325 * Compute a shell doublet of integrals and return as a borrowed
326 * sidl array.
327 * @param shellnum1 Gaussian shell number 1.
328 * @param shellnum2 Gaussian shell number 2.
329 * @param deriv_level Derivative level.
330 * @param deriv_ctr Derivative center descriptor.
331 * @return Borrowed sidl array buffer.
332 */
333::sidl::array<double>
334MPQC::IntegralEvaluator2_impl::compute_array (
335 /* in */ int64_t shellnum1,
336 /* in */ int64_t shellnum2,
337 /* in */ int64_t deriv_level,
338 /* in */ ::Chemistry::QC::GaussianBasis::DerivCenters deriv_ctr )
339throw ()
340{
341 // DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2.compute_array)
342
343 compute( shellnum1, shellnum2, deriv_level, deriv_ctr );
344
345 // create a proxy SIDL array
346 int lower[1] = {0};
347 int upper[1]; upper[0] = max_nshell2_-1;
348 int stride[1] = {1};
349 sidl_buffer_.borrow( const_cast<double*>(sc_buffer_), 1,
350 lower, upper, stride);
351 return sidl_buffer_;
352
353 // DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2.compute_array)
354}
355
356
357// DO-NOT-DELETE splicer.begin(MPQC.IntegralEvaluator2._misc)
358
359void
360MPQC::IntegralEvaluator2_impl::initialize_reorder_intv3()
361{
362
363 if( int_type_ == one_body )
364 temp_buffer_ = new double[max_nshell2_];
365 else if( int_type_ == one_body_deriv )
366 temp_buffer_ = new double[max_nshell2_*3];
367
368 reorder_ = new int*[maxam_+1];
369 reorder_[0] = new int[1];
370 reorder_[0][0] = 0;
371
372 for( int i=1; i<=maxam_; ++i) {
373
374 sc::CartesianIter *v3iter = integral_->new_cartesian_iter(i);
375 MPQC::CartesianIterCCA iter(i);
376 MPQC::CartesianIterCCA *ccaiter = &iter;
377 ccaiter->start();
378 int ncf = ccaiter->n();
379
380 reorder_[i] = new int[ncf];
381 v3iter->start();
382 for( int j=0; j<ncf; ++j) {
383 ccaiter->start();
384 for( int k=0; k<ncf; ++k) {
385 if( v3iter->a() == ccaiter->a() &&
386 v3iter->b() == ccaiter->b() &&
387 v3iter->c() == ccaiter->c() ) {
388 reorder_[i][j] = k;
389 k=ncf; //break k loop
390 }
391 else ccaiter->next();
392 }
393 v3iter->next();
394 }
395 }
396
397}
398
399
400void
401MPQC::IntegralEvaluator2_impl::reorder_intv3(int64_t shellnum1,int64_t shellnum2)
402{
403
404 sc::GaussianShell* s1 = &( bs1_->shell(shellnum1) );
405 sc::GaussianShell* s2 = &( bs2_->shell(shellnum2) );
406 int nc1 = s1->ncontraction();
407 int nc2 = s2->ncontraction();
408
409 int reorder_needed=0;
410 for (int i=0; i<nc1; ++i) {
411 if( s1->am(i) == 1) reorder_needed=1;
412 else if( s1->am(i) > 1 && s1->is_cartesian(i) ) reorder_needed=1;
413 }
414 if (!reorder_needed)
415 for (int i=0; i<nc2; ++i) {
416 if( s2->am(i) == 1) reorder_needed=1;
417 else if( s2->am(i) > 1 && s2->is_cartesian(i) ) reorder_needed=1;
418 }
419 if( !reorder_needed ) return;
420
421 // copy buffer into temp space
422 int nfunc = s1->nfunction() * s2->nfunction();
423 if( int_type_ == one_body_deriv )
424 for( int i=0; i<nfunc*3; ++i)
425 temp_buffer_[i] = sc_buffer_[i];
426 else
427 for( int i=0; i<nfunc; ++i)
428 temp_buffer_[i] = sc_buffer_[i];
429
430 // a derivative buffer is composed of 3 "doublets"
431 int deriv_offset;
432 if( int_type_ == one_body )
433 reorder_doublet( s1, s2, nc1, nc2, 0 );
434 else if( int_type_ == one_body_deriv )
435 for(int i=0; i<3; ++i) {
436 deriv_offset = i*nfunc;
437 std::cerr << "deriv offset is " << deriv_offset << std::endl;
438 reorder_doublet( s1, s2, nc1, nc2, deriv_offset );
439 }
440
441
442}
443
444
445
446void
447MPQC::IntegralEvaluator2_impl::reorder_doublet( sc::GaussianShell* s1, sc::GaussianShell* s2,
448 int nc1, int nc2, int deriv_offset )
449{
450
451 int index=deriv_offset, con2_offset=0, local2_offset,
452 c1_base, c2_base;
453
454 int temp;
455 for( int c2=0; c2<nc2; ++c2 )
456 con2_offset += s2->nfunction(c2);
457
458 int s1_is_cart, s2_is_cart, s1_nfunc, s2_nfunc;
459
460 for( int c1=0; c1<nc1; ++c1 ) {
461
462 c1_base = index;
463 s1_is_cart = s1->is_cartesian(c1);
464 s1_nfunc = s1->nfunction(c1);
465
466 for( int fc1=0; fc1<s1_nfunc; ++fc1 ) {
467
468 if( s1_is_cart )
469 c2_base = c1_base + reorder_[s1->am(c1)][fc1] * con2_offset;
470 else
471 c2_base = c1_base + fc1 * con2_offset;
472
473 local2_offset = 0;
474 for( int c2=0; c2<nc2; ++c2 ) {
475 if( c2>0 ) local2_offset += s2->nfunction(c2-1);
476 s2_is_cart = s2->is_cartesian(c2);
477 s2_nfunc = s2->nfunction(c2);
478
479 if( s2_is_cart )
480 for( int fc2=0; fc2<s2_nfunc; ++fc2 ) {
481 buf_[ c2_base + local2_offset + reorder_[s2->am(c2)][fc2] ]
482 = temp_buffer_[index];
483 ++index;
484 }
485 else
486 for( int fc2=0; fc2<s2_nfunc; ++fc2 ) {
487 buf_[ c2_base + local2_offset + fc2 ] = temp_buffer_[index];
488 ++index;
489 }
490 }
491 }
492 }
493
494}
495
496// DO-NOT-DELETE splicer.end(MPQC.IntegralEvaluator2._misc)
497
Note: See TracBrowser for help on using the repository browser.