source: ThirdParty/mpqc_open/src/lib/chemistry/qc/intv3/inttest.cc

Candidate_v1.6.1
Last change on this file was 251420, checked in by Frederik Heber <heber@…>, 8 years ago

Fixed all src/lib's Makefile.am's linking.

  • Property mode set to 100644
File size: 25.1 KB
Line 
1//
2// inttest.cc
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Curtis Janssen <cljanss@limitpt.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#include <stdlib.h>
29#include <string.h>
30
31#include <util/misc/formio.h>
32#include <util/misc/regtime.h>
33#include <util/keyval/keyval.h>
34#include <util/group/message.h>
35#include <util/group/pregtime.h>
36#include <chemistry/qc/intv3/int1e.h>
37#include <chemistry/qc/intv3/int2e.h>
38#include <chemistry/qc/intv3/intv3.h>
39
40using namespace std;
41using namespace sc;
42
43void test_int_shell_1e(const Ref<KeyVal>&, const Ref<Int1eV3> &int1ev3,
44 void (Int1eV3::*int_shell_1e)(int,int),
45 int permute);
46void test_3_center(const Ref<KeyVal>&, const Ref<Int2eV3> &);
47void test_4_center(const Ref<KeyVal>& keyval, const Ref<Int2eV3> &int2ev3);
48void test_4der_center(const Ref<KeyVal>&, const Ref<Int2eV3> &int2ev3);
49
50#define maxint 9
51
52void
53testint(const Ref<OneBodyInt>& in)
54{
55 if (in.null()) {
56 cout << "null integral generator" << endl;
57 abort();
58 }
59}
60
61void
62testint(const Ref<OneBodyDerivInt>& in)
63{
64 if (in.null()) {
65 cout << "null integral generator" << endl;
66 abort();
67 }
68}
69
70void
71testint(const Ref<TwoBodyInt>& in)
72{
73 if (in.null()) {
74 cout << "null integral generator" << endl;
75 abort();
76 }
77}
78
79void
80testint(const Ref<TwoBodyDerivInt>& in)
81{
82 if (in.null()) {
83 cout << "null integral generator" << endl;
84 abort();
85 }
86}
87
88void
89do_bounds_stats(const Ref<KeyVal>& keyval,
90 const Ref<Int2eV3> &int2ev3)
91{
92 int i,j;
93 int nshell = int2ev3->basis()->nshell();
94 int eps = -10;
95 int *nonzero = new int[nshell];
96 for (i=0; i<nshell; i++) {
97 if (i==0) nonzero[i] = 0;
98 else nonzero[i] = nonzero[i-1];
99 for (j=0; j<=i; j++) {
100 if (int2ev3->erep_4bound(i,j,-1,-1) > eps) {
101 nonzero[i]++;
102 }
103 }
104 }
105 for (i=0; i<nshell; i++) {
106 int natom = 1 + int2ev3->basis()->shell_to_center(i);
107 int npq = (i*(i+1))/2;
108 cout<<scprintf("nsh=%2d nat=%2d npq=%4d npq>eps=%4d npq>eps/nsh=%9.4f /nat=%9.4f",
109 i, natom, npq, nonzero[i], double(nonzero[i])/i,
110 double(nonzero[i])/natom)
111 << endl;
112 }
113 delete[] nonzero;
114}
115
116int
117main(int argc, char **argv)
118{
119 int ii, i,j,k,l,m,n;
120
121 Ref<MessageGrp> msg = MessageGrp::initial_messagegrp(argc,argv);
122 if (msg.null()) msg = new ProcMessageGrp();
123 MessageGrp::set_default_messagegrp(msg);
124
125 Ref<RegionTimer> tim = new ParallelRegionTimer(msg,"inttest", 1, 1);
126
127 char *infile = new char[strlen(SRCDIR)+strlen("/inttest.in")+1];
128 sprintf(infile,SRCDIR "/inttest.in");
129 if (argc == 2) {
130 infile = argv[1];
131 }
132
133 Ref<KeyVal> pkv(new ParsedKeyVal(infile));
134 Ref<KeyVal> tkeyval(new PrefixKeyVal(pkv, ":test"));
135
136 Ref<GaussianBasisSet> basis = require_dynamic_cast<GaussianBasisSet*>(
137 tkeyval->describedclassvalue("basis").pointer(),"main\n");
138 Ref<Molecule> mol = basis->molecule();
139
140 int tproc = tkeyval->intvalue("test_processor");
141 if (tproc >= msg->n()) tproc = 0;
142 int me = msg->me();
143
144 if (me == tproc) cout << "testing on processor " << tproc << endl;
145
146 int storage = tkeyval->intvalue("storage");
147 cout << "storage = " << storage << endl;
148 Ref<Integral> intgrl = new IntegralV3(basis,basis,basis,basis);
149 Ref<Int1eV3> int1ev3 = new Int1eV3(intgrl.pointer(),basis,basis,1);
150 Ref<Int2eV3> int2ev3 = new Int2eV3(intgrl.pointer(),basis,basis,basis,basis,
151 1, storage);
152
153 int permute = tkeyval->booleanvalue("permute");
154 tim->enter("overlap");
155 if (me == tproc && tkeyval->booleanvalue("overlap")) {
156 cout << scprintf("testing overlap:\n");
157 test_int_shell_1e(tkeyval, int1ev3, &Int1eV3::overlap, permute);
158 }
159 tim->change("kinetic");
160 if (me == tproc && tkeyval->booleanvalue("kinetic")) {
161 cout << scprintf("testing kinetic:\n");
162 test_int_shell_1e(tkeyval, int1ev3, &Int1eV3::kinetic, permute);
163 }
164 tim->change("hcore");
165 if (me == tproc && tkeyval->booleanvalue("hcore")) {
166 cout << scprintf("testing hcore:\n");
167 test_int_shell_1e(tkeyval, int1ev3, &Int1eV3::hcore, permute);
168 }
169 tim->change("nuclear");
170 if (me == tproc && tkeyval->booleanvalue("nuclear")) {
171 cout << scprintf("testing nuclear:\n");
172 test_int_shell_1e(tkeyval, int1ev3, &Int1eV3::nuclear, permute);
173 }
174 tim->change("3 center");
175 if (me == tproc && tkeyval->booleanvalue("3")) {
176 test_3_center(tkeyval, int2ev3);
177 }
178 tim->change("4 center");
179 if (me == tproc && tkeyval->booleanvalue("4")) {
180 test_4_center(tkeyval, int2ev3);
181 }
182 tim->change("4 center der");
183 if (me == tproc && tkeyval->booleanvalue("4der")) {
184 test_4der_center(tkeyval, int2ev3);
185 }
186 tim->change("bound stats");
187 if (me == tproc && tkeyval->booleanvalue("boundstats")) {
188 do_bounds_stats(tkeyval, int2ev3);
189 }
190
191 tim->change("IntegralV3");
192 Ref<Integral> integral = new IntegralV3(basis);
193 Ref<OneBodyInt> overlap = integral->overlap();
194 testint(overlap);
195 Ref<OneBodyInt> kinetic = integral->kinetic();
196 testint(kinetic);
197 Ref<OneBodyDerivInt> kinetic_der = integral->kinetic_deriv();
198 testint(kinetic_der);
199 Ref<OneBodyDerivInt> overlap_der = integral->overlap_deriv();
200 testint(overlap_der);
201 Ref<OneBodyDerivInt> nuclear_der = integral->nuclear_deriv();
202 testint(nuclear_der);
203 Ref<TwoBodyInt> erep = integral->electron_repulsion();
204 testint(erep);
205 Ref<TwoBodyDerivInt> erep_der = integral->electron_repulsion_deriv();
206 testint(erep_der);
207 tim->exit();
208
209 tim->print();
210 return 0;
211}
212
213void
214do_shell_test_1e(const Ref<Int1eV3> &int1ev3,
215 void (Int1eV3::*int_shell_1e)(int,int),
216 int permute, int i, int j, int na, int nb,
217 double *buf, double *pbuf)
218{
219 int ii = 0;
220 int a;
221 double *buffer = int1ev3->buffer();
222 (int1ev3.pointer()->*int_shell_1e)(i, j);
223 for (a=0; a<na*nb; a++) {
224 buf[a] = buffer[a];
225 }
226 (int1ev3.pointer()->*int_shell_1e)(j, i);
227 for (a=0; a<na*nb; a++) {
228 pbuf[a] = buffer[a];
229 }
230 for (a=0; a<na; a++) {
231 for (int b=0; b<nb; b++) {
232 if (fabs(buf[ii] - pbuf[a + na*b]) > 1.0e-13) {
233 cout << scprintf("----- 1e perm failed:"
234 "<%d %d|%d %d>:"
235 " %18.14f != %18.14f "
236 "<%d %d|%d %d>\n",
237 i, a, j, b,
238 buf[ii],
239 pbuf[a + na*b],
240 j, b, i, a);
241 }
242 if (fabs(buf[ii]) > 1.0e-15) {
243 cout << scprintf(" <(%d %d)|(%d %d)> = %15.11f\n",
244 i,a,j,b, buf[ii]);
245 }
246 ii++;
247 }
248 }
249}
250
251void
252test_int_shell_1e(const Ref<KeyVal>& keyval, const Ref<Int1eV3> &int1ev3,
253 void (Int1eV3::*int_shell_1e)(int,int),
254 int permute)
255{
256 int flags = 0;
257 Ref<GaussianBasisSet> basis = int1ev3->basis();
258 int maxfunc = basis->max_nfunction_in_shell();
259 int size = maxfunc * maxfunc;
260 double *buf = new double[size];
261 double *pbuf = new double[size];
262 int nshell = int1ev3->basis()->nshell();
263
264 for (int i=0; i<nshell; i++) {
265 int na = basis->shell(i).nfunction();
266 for (int j=0; j<nshell; j++) {
267 int nb = basis->shell(j).nfunction();
268 do_shell_test_1e(int1ev3, int_shell_1e, permute,
269 i, j, na, nb, buf, pbuf);
270
271 }
272 }
273
274 delete[] buf;
275 delete[] pbuf;
276}
277
278void
279test_3_center(const Ref<KeyVal>& keyval, const Ref<Int2eV3> &int2ev3)
280{
281 int ii, i,j,k,l,m,n;
282
283 int2ev3->set_redundant(1);
284 int2ev3->set_permute(0);
285 double *buffer = int2ev3->buffer();
286 int nshell = int2ev3->basis()->nshell();
287
288 for (i=0; i<nshell; i++) {
289 for (j=0; j<nshell; j++) {
290 int sh[2], sizes[2];
291 sh[0] = i;
292 sh[1] = j;
293 int2ev3->erep_2center(sh,sizes);
294 ii = 0;
295 for (k=0; k<sizes[0]; k++) {
296 for (l=0; l<sizes[1]; l++) {
297 if (fabs(buffer[ii])>1.0e-15)
298 cout << scprintf(" ((%d %d)|(%d %d)) = %15.11f\n",
299 sh[0],k,sh[1],l, buffer[ii]);
300 ii++;
301 }
302 }
303 }
304 }
305
306 for (i=0; i<nshell; i++) {
307 for (j=0; j<nshell; j++) {
308 for (m=0; m<nshell; m++) {
309 int sh[3], sizes[3];
310 sh[0] = i;
311 sh[1] = j;
312 sh[2] = m;
313 int2ev3->erep_3center(sh,sizes);
314 ii = 0;
315 for (k=0; k<sizes[0]; k++) {
316 for (l=0; l<sizes[1]; l++) {
317 for (n=0; n<sizes[2]; n++) {
318 if (fabs(buffer[ii])>1.0e-15)
319 cout << scprintf(
320 " ((%d %d)|(%d %d)(%d %d)) = %15.11f\n",
321 sh[0],k,sh[1],l,sh[2],n, buffer[ii]);
322 ii++;
323 }
324 }
325 }
326 }
327 }
328 }
329
330}
331
332void
333init_shell_perm(const Ref<Int2eV3> &int2ev3, double *integrals,
334 double buff[maxint][maxint][maxint][maxint],
335 int sh[4], int sizes[4])
336{
337 int i, j, k, l;
338 int oldp = int2ev3->permute();
339 int2ev3->set_permute(0);
340 int2ev3->erep(sh, sizes);
341 int2ev3->set_permute(oldp);
342 for (i=0; i<sizes[0]; i++) {
343 for (j=0; j<sizes[1]; j++) {
344 for (k=0; k<sizes[2]; k++) {
345 for (l=0; l<sizes[3]; l++) {
346 buff[i][j][k][l] = *integrals++;
347 }
348 }
349 }
350 }
351}
352
353void
354check_shell_perm(const Ref<Int2eV3> &int2ev3, double *integrals,
355 double buff[maxint][maxint][maxint][maxint],
356 int sh[4], int sizes[4], int p0, int p1, int p2, int p3)
357{
358 int ip[4], p[4];
359 int psizes[4];
360 int psh[4];
361 int index = 0;
362 int i[4];
363 p[0] = p0;
364 p[1] = p1;
365 p[2] = p2;
366 p[3] = p3;
367 ip[p0] = 0;
368 ip[p1] = 1;
369 ip[p2] = 2;
370 ip[p3] = 3;
371 psh[0] = sh[p0];
372 psh[1] = sh[p1];
373 psh[2] = sh[p2];
374 psh[3] = sh[p3];
375 int oldp = int2ev3->permute();
376 int2ev3->set_permute(0);
377 int2ev3->erep(psh, psizes);
378 int2ev3->set_permute(oldp);
379 for (i[0]=0; i[0]<psizes[0]; i[0]++) {
380 for (i[1]=0; i[1]<psizes[1]; i[1]++) {
381 for (i[2]=0; i[2]<psizes[2]; i[2]++) {
382 for (i[3]=0; i[3]<psizes[3]; i[3]++) {
383 if (fabs(buff[i[ip[0]]][i[ip[1]]][i[ip[2]]][i[ip[3]]]
384 - integrals[index]) > 1.0e-13) {
385 cout << scprintf("perm %d %d %d %d failed:"
386 "((%d %d)(%d %d)|(%d %d)(%d %d)):"
387 " %18.14f != %18.14f "
388 "((%d %d)(%d %d)|(%d %d)(%d %d))\n",
389 p0, p1, p2, p3,
390 sh[0],i[0], sh[1],i[1], sh[2],i[2], sh[3],i[3],
391 buff[i[ip[0]]][i[ip[1]]][i[ip[2]]][i[ip[3]]],
392 integrals[index],
393 psh[0],i[p[0]], psh[1],i[p[1]],
394 psh[2],i[p[2]], psh[3],i[p[3]]);
395 }
396 index++;
397 }
398 }
399 }
400 }
401}
402
403void
404do_shell_quartet_test(const Ref<Int2eV3> &int2ev3,
405 int print, int printbounds, int bounds, int permute,
406 const Ref<KeyVal>& keyval,
407 int i, int j, int k, int l)
408{
409 int sh[4], sizes[4];
410 int ibuf;
411 int ii, jj, kk, ll;
412 sh[0] = i;
413 sh[1] = j;
414 sh[2] = k;
415 sh[3] = l;
416 double maxintegral, integralbound;
417 int boundijkl;
418 if (bounds) {
419 integralbound
420 = int2ev3->logbound_to_bound(
421 (boundijkl = int2ev3->erep_4bound(i,j,k,l))
422 );
423 }
424 double *buffer = int2ev3->buffer();
425 int2ev3->erep(sh,sizes);
426 ibuf = 0;
427 maxintegral = 0.0;
428 for (ii=0; ii<sizes[0]; ii++) {
429 for (jj=0; jj<sizes[1]; jj++) {
430 for (kk=0; kk<sizes[2]; kk++) {
431 for (ll=0; ll<sizes[3]; ll++) {
432 double absint = fabs(buffer[ibuf]);
433 if (absint > maxintegral) {
434 maxintegral = absint;
435 }
436 if (bounds && absint > integralbound) {
437 cout << scprintf("((%d %d)(%d %d)|(%d %d)(%d %d)) = %15.11f, "
438 "bound = %15.11f\n",
439 sh[0], ii, sh[1], jj, sh[2], kk, sh[3], ll,
440 buffer[ibuf], integralbound);
441 abort();
442 }
443 if (print && (absint > 1.0e-9
444 || (bounds && integralbound > 1.0e-9))) {
445 cout << scprintf(" ((%d %d)(%d %d)|(%d %d)(%d %d))"
446 " = %15.11f",
447 sh[0],ii,
448 sh[1],jj,
449 sh[2],kk,
450 sh[3],ll,
451 buffer[ibuf]);
452 if (bounds) {
453 cout << scprintf(" (%2d%% of bound)",
454 (int)(100*(absint/integralbound)));
455 }
456 cout << scprintf("\n");
457 }
458 ibuf++;
459 }
460 }
461 }
462 }
463
464 if (permute) {
465 double buff1[maxint][maxint][maxint][maxint];
466 sh[0] = i;
467 sh[1] = j;
468 sh[2] = k;
469 sh[3] = l;
470 init_shell_perm(int2ev3, buffer, buff1, sh, sizes);
471 check_shell_perm(int2ev3, buffer, buff1, sh, sizes, 0, 1, 2, 3);
472 check_shell_perm(int2ev3, buffer, buff1, sh, sizes, 1, 0, 2, 3);
473 check_shell_perm(int2ev3, buffer, buff1, sh, sizes, 0, 1, 3, 2);
474 check_shell_perm(int2ev3, buffer, buff1, sh, sizes, 1, 0, 3, 2);
475 check_shell_perm(int2ev3, buffer, buff1, sh, sizes, 2, 3, 0, 1);
476 check_shell_perm(int2ev3, buffer, buff1, sh, sizes, 2, 3, 1, 0);
477 check_shell_perm(int2ev3, buffer, buff1, sh, sizes, 3, 2, 0, 1);
478 check_shell_perm(int2ev3, buffer, buff1, sh, sizes, 3, 2, 1, 0);
479 }
480
481 if (bounds) {
482 int boundij = int2ev3->erep_4bound(i,j,-1,-1);
483 int boundkl = int2ev3->erep_4bound(-1,-1,k,l);
484 int badbound = 0;
485 if (boundij < boundijkl || boundkl < boundijkl) {
486 badbound = 1;
487 }
488 if (badbound || printbounds) {
489 cout << scprintf("max(%d,%d,%d,%d)=%7.4f, bnd=%7.4f, "
490 "bnd(%d,%d,*,*)=%7.4f, bnd(*,*,%d,%d)=%7.4f\n",
491 i, j, k, l, maxintegral, integralbound,
492 i,j, int2ev3->logbound_to_bound(boundij),
493 k,l, int2ev3->logbound_to_bound(boundkl));
494 }
495 if (badbound) {
496 cout << scprintf("ERROR: bad bound\n");
497 abort();
498 }
499 }
500}
501
502void
503do_4_center_test(const Ref<Int2eV3> &int2ev3, int print, int printbounds,
504 int bounds, int permute,
505 const Ref<KeyVal>& keyval)
506{
507 int ii,jj,kk,ll, i,j,k,l, ibuf;
508 int nshell = int2ev3->basis()->nshell();
509 int unique = keyval->booleanvalue("unique");
510 int timestats = keyval->booleanvalue("timestats");
511 Ref<RegionTimer> timer = new RegionTimer();
512
513 if (!timestats) {
514 for (i=0; i<nshell; i++) {
515 int jmax = nshell - 1;
516 if (unique) jmax = i;
517 for (j=0; j<=jmax; j++) {
518 int kmax = nshell - 1;
519 if (unique) kmax = i;
520 for (k=0; k<=kmax; k++) {
521 int lmax = nshell - 1;
522 if (unique) {
523 if (k==i) lmax = j;
524 else lmax = k;
525 }
526 for (l=0; l<=lmax; l++) {
527 do_shell_quartet_test(int2ev3, print, printbounds,
528 bounds, permute,
529 keyval, i, j, k, l);
530 }
531 }
532 }
533 }
534 }
535 if (timestats && nshell) {
536 unsigned short seed = 1234;
537 seed48(&seed);
538 const int nsample = 5000;
539 const int ntrials = 50;
540 double times[ntrials];
541 for (i=0; i<ntrials; i++) {
542 double t1 = timer->get_cpu_time();
543 for (j=0; j<nsample; j++) {
544 // pick an integral at random
545 int ish = int(drand48()*nshell);
546 int jsh = int(drand48()*ish);
547 int ksh = int(drand48()*ish);
548 int lsh;
549 if (ish==ksh) lsh = int(drand48()*jsh);
550 else lsh = int(drand48()*ksh);
551 int sh[4], sizes[4];
552 if (ish >= nshell) ish = nshell-1;
553 if (jsh >= nshell) jsh = nshell-1;
554 if (ksh >= nshell) ksh = nshell-1;
555 if (lsh >= nshell) lsh = nshell-1;
556 sh[0] = ish;
557 sh[1] = jsh;
558 sh[2] = ksh;
559 sh[3] = lsh;
560 int2ev3->erep(sh,sizes);
561 }
562 double t2 = timer->get_cpu_time();
563 times[i] = t2-t1;
564 }
565 double ave = 0.0;
566 for (i=0; i<ntrials; i++) {
567 ave += times[i];
568 }
569 ave /= ntrials;
570 double sigma2 = 0.0;
571 for (i=0; i<ntrials; i++) {
572 double diff = times[i] - ave;
573 sigma2 += diff*diff;
574 }
575 double sigma = sqrt(sigma2/ntrials);
576 // adjust sigma and ave from the trial average results to
577 // the integral results
578 ave /= nsample;
579 sigma /= sqrt(double(nsample));
580 cout << scprintf(" ave = %10.8f sigma = %10.8f (microsecs)\n"
581 " sigma/ave = %10.4f",
582 ave*1e6, sigma*1e6,
583 sigma/ave)
584 << endl;
585 }
586}
587
588void
589test_4_center(const Ref<KeyVal>& keyval, const Ref<Int2eV3> &int2ev3)
590{
591 int i;
592
593 cout << scprintf("4 center test:\n");
594 cout << scprintf(" on entry int2ev3 used %d bytes\n", int2ev3->used_storage());
595
596 int2ev3->set_permute(0);
597 int2ev3->set_redundant(1);
598
599 int storage = keyval->intvalue("storage") - int2ev3->used_storage();
600 if (storage < 0) storage = 0;
601 if (keyval->booleanvalue("store_integrals")) storage = 0;
602 int niter = keyval->intvalue("niter");
603 int print = keyval->booleanvalue("print");
604 int bounds = keyval->booleanvalue("bounds");
605 int permute = keyval->booleanvalue("permute");
606 int printbounds = keyval->booleanvalue("printbounds");
607
608 cout << scprintf(" storage = %d\n", storage);
609 cout << scprintf(" niter = %d\n", niter);
610 cout << scprintf(" print = %d\n", print);
611 cout << scprintf(" bounds = %d\n", bounds);
612 cout << scprintf(" permute = %d\n", permute);
613 cout << scprintf("printbounds = %d\n", printbounds);
614
615 if (bounds) int2ev3->init_bounds();
616
617 int2ev3->init_storage(storage);
618
619 for (i=0; i<niter; i++) {
620 do_4_center_test(int2ev3, print, printbounds, bounds, permute, keyval);
621 }
622
623 if (keyval->count("quartet") == 4) {
624 do_shell_quartet_test(int2ev3, print, printbounds, bounds, permute,
625 keyval,
626 keyval->intvalue("quartet", 0),
627 keyval->intvalue("quartet", 1),
628 keyval->intvalue("quartet", 2),
629 keyval->intvalue("quartet", 3));
630 }
631
632 int2ev3->done_storage();
633 int2ev3->done_bounds();
634}
635
636void
637do_shell_quartet_der_test(const Ref<Int2eV3> &int2ev3,
638 double* buffer, int print, int printbounds,
639 int bounds, int permute,
640 const Ref<KeyVal>& keyval,
641 int i, int j, int k, int l)
642{
643 int ii,jj,kk,ll, ibuf, ider, xyz;
644 der_centersv3_t dercenters;
645
646 int sh[4], sizes[4];
647 sh[0] = i;
648 sh[1] = j;
649 sh[2] = k;
650 sh[3] = l;
651 double maxintegral = 0.0, integralbound;
652 int boundijkl;
653 if (bounds) {
654 integralbound
655 = int2ev3->logbound_to_bound(
656 (boundijkl = int2ev3->erep_4bound_1der(i,j,k,l))
657 );
658 }
659 int2ev3->erep_all1der(sh,sizes,&dercenters);
660 ibuf = 0;
661 for (ider=0; ider<dercenters.n; ider++) {
662 for (xyz=0; xyz<3; xyz++) {
663 for (ii=0; ii<sizes[0]; ii++) {
664 for (jj=0; jj<sizes[1]; jj++) {
665 for (kk=0; kk<sizes[2]; kk++) {
666 for (ll=0; ll<sizes[3]; ll++) {
667 double absint = fabs(buffer[ibuf]);
668 if (absint > maxintegral) {
669 maxintegral = absint;
670 }
671 if (bounds && absint > integralbound) {
672 cout << scprintf("((%d %d)(%d %d)|(%d %d)(%d %d))"
673 " = %15.11f, bound = %15.11f\n",
674 sh[0], ii, sh[1], jj,
675 sh[2], kk, sh[3], ll,
676 buffer[ibuf], integralbound);
677 abort();
678 }
679 if (print && absint > 1.0e-15) {
680 cout << scprintf(" ((%d %d)(%d %d)"
681 "|(%d %d)(%d %d))(%d %d)"
682 " = %15.11f\n",
683 sh[0],ii,
684 sh[1],jj,
685 sh[2],kk,
686 sh[3],ll,
687 dercenters.num[ider], xyz,
688 buffer[ibuf]
689 );
690 }
691 ibuf++;
692 }
693 }
694 }
695 }
696 }
697 }
698
699 if (bounds) {
700 int boundij = int2ev3->erep_4bound_1der(i,j,-1,-1);
701 int boundkl = int2ev3->erep_4bound_1der(-1,-1,k,l);
702 int badbound = 0;
703 if (boundij < boundijkl || boundkl < boundijkl) {
704 badbound = 1;
705 }
706 if (badbound || printbounds) {
707 cout << scprintf("max(%d,%d,%d,%d)=%7.4f, bnd=%7.4f, "
708 "bnd(%d,%d,*,*)=%8.4f, bnd(*,*,%d,%d)=%8.4f\n",
709 i, j, k, l, maxintegral, integralbound,
710 i,j, int2ev3->logbound_to_bound(boundij),
711 k,l, int2ev3->logbound_to_bound(boundkl));
712 }
713 if (badbound) {
714 cout << scprintf("ERROR: bad bound\n");
715 abort();
716 }
717 }
718}
719
720void
721do_test_4der_center(const Ref<Int2eV3> &int2ev3,
722 double* buffer, int print, int printbounds,
723 int bounds, int permute,
724 const Ref<KeyVal>& keyval)
725{
726 int i,j,k,l;
727 int nshell = int2ev3->basis()->nshell();
728 for (i=0; i<nshell; i++) {
729 for (j=0; j<nshell; j++) {
730 for (k=0; k<nshell; k++) {
731 for (l=0; l<nshell; l++) {
732 do_shell_quartet_der_test(int2ev3, buffer,
733 print, printbounds,
734 bounds, permute,
735 keyval,
736 i, j, k, l);
737 }
738 }
739 }
740 }
741}
742
743void
744test_4der_center(const Ref<KeyVal>& keyval, const Ref<Int2eV3> &int2ev3)
745{
746 int i;
747
748 int2ev3->set_permute(0);
749 int2ev3->set_redundant(1);
750 double *buffer = int2ev3->buffer();
751
752 int niter = keyval->intvalue("niter");
753 int print = keyval->booleanvalue("print");
754 int bounds = keyval->booleanvalue("bounds");
755 int printbounds = keyval->booleanvalue("printbounds");
756 int permute = keyval->booleanvalue("permute");
757
758 cout << scprintf("4 center derivative test:\n");
759 cout << scprintf(" niter = %d\n", niter);
760 cout << scprintf(" print = %d\n", print);
761 cout << scprintf(" bounds = %d\n", bounds);
762 cout << scprintf("printbounds = %d\n", printbounds);
763 cout << scprintf(" permute = %d\n", permute);
764
765 if (bounds) int2ev3->init_bounds_1der();
766
767 for (i=0; i<niter; i++) {
768 do_test_4der_center(int2ev3, buffer,
769 print, printbounds, bounds, permute, keyval);
770 }
771
772 if (keyval->count("quartet") == 4) {
773 do_shell_quartet_der_test(int2ev3, buffer, print, printbounds,
774 bounds, permute,
775 keyval,
776 keyval->intvalue("quartet", 0),
777 keyval->intvalue("quartet", 1),
778 keyval->intvalue("quartet", 2),
779 keyval->intvalue("quartet", 3));
780 }
781
782 if (bounds) int2ev3->done_bounds_1der();
783}
784
785/////////////////////////////////////////////////////////////////////////////
786
787// Local Variables:
788// mode: c++
789// c-file-style: "CLJ"
790// End:
Note: See TracBrowser for help on using the repository browser.