source: ThirdParty/mpqc_open/src/lib/chemistry/qc/mbpt/csgmat.cc@ aae63a

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction Subpackage_levmar Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since aae63a 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: 20.7 KB
Line 
1//
2// csgmat.cc
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Ida Nielsen <ida@kemi.aau.dk>
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 <string.h>
29#include <stdlib.h>
30#include <math.h>
31#include <limits.h>
32
33#include <util/misc/timer.h>
34#include <util/misc/formio.h>
35#include <math/scmat/matrix.h>
36#include <math/scmat/local.h>
37#include <math/scmat/repl.h>
38#include <chemistry/qc/mbpt/mbpt.h>
39#include <chemistry/qc/basis/petite.h>
40#include <chemistry/qc/scf/lgbuild.h>
41#include <chemistry/qc/scf/clhftmpl.h>
42
43using namespace sc;
44
45#define ioff(i) (((i)*((i)+1))>>1)
46#define IOFF(a,b) (((a)>(b))?(ioff(a)+(b)):(ioff(b)+(a)))
47
48#define INT_MAX1(n1) ((n1)-1)
49#define INT_MAX2(e12,i,n2) ((e12)?(i):((n2)-1))
50#define INT_MAX3(e13e24,i,n3) ((e13e24)?(i):((n3)-1))
51#define INT_MAX4(e13e24,e34,i,j,k,n4) \
52 ((e34)?(((e13e24)&&((k)==(i)))?(j):(k)) \
53 :((e13e24)&&((k)==(i)))?(j):(n4)-1)
54
55enum Access { Read, Write, Accum };
56static RefSymmSCMatrix
57get_local_data(const RefSymmSCMatrix& m, double*& p,
58 const Ref<MessageGrp> &msg, Access access)
59{
60 RefSymmSCMatrix l = m;
61
62 if (!dynamic_cast<LocalSymmSCMatrix*>(l.pointer())
63 && !dynamic_cast<ReplSymmSCMatrix*>(l.pointer())) {
64 Ref<SCMatrixKit> k = new ReplSCMatrixKit;
65 l = k->symmmatrix(m.dim());
66 l->convert(m);
67
68 if (access == Accum)
69 l->assign(0.0);
70 } else if (msg->n() > 1 && access==Accum) {
71 l = m.clone();
72 l.assign(0.0);
73 }
74
75 if (dynamic_cast<ReplSymmSCMatrix*>(l.pointer()))
76 p = dynamic_cast<ReplSymmSCMatrix*>(l.pointer())->get_data();
77 else
78 p = dynamic_cast<LocalSymmSCMatrix*>(l.pointer())->get_data();
79
80 return l;
81}
82
83static signed char *
84init_pmax(double *pmat_data, const Ref<GaussianBasisSet> &basis)
85{
86 double l2inv = 1.0/log(2.0);
87 double tol = pow(2.0,-126.0);
88
89 GaussianBasisSet& gbs = *basis.pointer();
90
91 signed char * pmax = new signed char[ioff(gbs.nshell())];
92
93 int ish, jsh, ij;
94 for (ish=ij=0; ish < gbs.nshell(); ish++) {
95 int istart = gbs.shell_to_function(ish);
96 int iend = istart + gbs(ish).nfunction();
97
98 for (jsh=0; jsh <= ish; jsh++,ij++) {
99 int jstart = gbs.shell_to_function(jsh);
100 int jend = jstart + gbs(jsh).nfunction();
101
102 double maxp=0, tmp;
103
104 for (int i=istart; i < iend; i++) {
105 int ijoff = ioff(i) + jstart;
106 for (int j=jstart; j < ((ish==jsh) ? i+1 : jend); j++,ijoff++)
107 if ((tmp=::fabs(pmat_data[ijoff])) > maxp)
108 maxp=tmp;
109 }
110
111 if (maxp <= tol)
112 maxp=tol;
113
114 long power = long(log(maxp)*l2inv);
115 if (power < SCHAR_MIN) pmax[ij] = SCHAR_MIN;
116 else if (power > SCHAR_MAX) pmax[ij] = SCHAR_MAX;
117 else pmax[ij] = (signed char) power;
118 }
119 }
120
121 return pmax;
122}
123
124/**************************************************************************
125 *
126 * calculate the closed shell G matrix
127 * assume all matrices are held locally -- IMBN
128 *
129 * input:
130 * Gmat = matrix containing old G matrix
131 * DPmat = matrix containing density diff matrix
132 *
133 * on return:
134 * Gmat contains the new G matrix
135 *
136 * return 0 on success and -1 on failure
137 */
138
139int
140MBPT2::make_cs_gmat_new(RefSymmSCMatrix& Gmat,
141 const RefSymmSCMatrix& DPmat)
142{
143 int i;
144 int nthread = thr_->nthread();
145
146 tim_enter("gmat");
147
148 Ref<PetiteList> pl = integral()->petite_list(basis());
149
150 Gmat.assign(0.0);
151
152 // scale the off-diagonal elements of DPmat by 2.0
153 DPmat->scale(2.0);
154 DPmat->scale_diagonal(0.5);
155
156 // now try to figure out the matrix specialization we're dealing with
157 // if we're using Local matrices, then there's just one subblock, or
158 // see if we can convert G and P to local matrices
159
160 if (debug_>1) {
161 DPmat.print("DPmat before build");
162 }
163
164 // grab the data pointers from the G and P matrices
165 double *gmat, *pmat;
166 RefSymmSCMatrix gtmp = get_local_data(Gmat, gmat, msg_, Accum);
167 RefSymmSCMatrix ptmp = get_local_data(DPmat, pmat, msg_, Read);
168
169 signed char * pmax = init_pmax(pmat, basis());
170
171 LocalGBuild<LocalCLHFContribution> **gblds =
172 new LocalGBuild<LocalCLHFContribution>*[nthread];
173 LocalCLHFContribution **conts = new LocalCLHFContribution*[nthread];
174
175 double **gmats = new double*[nthread];
176 gmats[0] = gmat;
177
178 Ref<GaussianBasisSet> bs = basis();
179 int ntri = ioff(bs->nbasis());
180
181 for (i=0; i < nthread; i++) {
182 if (i) {
183 gmats[i] = new double[ntri];
184 memset(gmats[i], 0, sizeof(double)*ntri);
185 }
186 conts[i] = new LocalCLHFContribution(gmats[i], pmat);
187 gblds[i] = new LocalGBuild<LocalCLHFContribution>(*conts[i], tbints_[i],
188 pl, bs, msg_, pmax, cphf_epsilon_/1000.0, nthread, i
189 );
190
191 thr_->add_thread(i, gblds[i]);
192 }
193
194 if (thr_->start_threads() < 0) {
195 ExEnv::err0() << indent
196 << "MBPT: csgmat: error starting threads" << std::endl;
197 abort();
198 }
199
200 if (thr_->wait_threads() < 0) {
201 ExEnv::err0() << indent
202 << "MBPT: csgmat: error waiting for threads" << std::endl;
203 abort();
204 }
205
206 double tnint=0;
207 for (i=0; i < nthread; i++) {
208 tnint += gblds[i]->tnint;
209
210 if (i) {
211 for (int j=0; j < ntri; j++)
212 gmat[j] += gmats[i][j];
213 delete[] gmats[i];
214 }
215
216 delete gblds[i];
217 delete conts[i];
218 }
219
220 delete[] gmats;
221 delete[] gblds;
222 delete[] conts;
223 delete[] pmax;
224
225 msg_->sum(&tnint, 1, 0, 0);
226 //ExEnv::out0() << indent << scprintf("%20.0f integrals\n", tnint);
227
228 // if we're running on multiple processors, then sum the G matrix
229 if (msg_->n() > 1)
230 msg_->sum(gmat, ioff(basis()->nbasis()));
231
232 // if we're running on multiple processors, or we don't have local
233 // matrices, then accumulate gtmp back into G
234 int local = (dynamic_cast<LocalSCMatrixKit*>(basis()->matrixkit().pointer()) ||
235 dynamic_cast<ReplSCMatrixKit*>(basis()->matrixkit().pointer())) ? 1:0;
236 if (!local || msg_->n() > 1)
237 Gmat->convert_accumulate(gtmp);
238
239 // now symmetrize the skeleton G matrix, placing the result in dd
240 Gmat.scale(1.0/(double)pl->order());
241 RefSymmSCMatrix Gmat_so(so_dimension(), basis_matrixkit());
242 if (debug_>1) {
243 Gmat.print("skeleton Gmat before symmetrize");
244 }
245 pl->symmetrize(Gmat,Gmat_so);
246 if (debug_>1) {
247 Gmat_so.print("Gmat in SO basis");
248 }
249 Gmat = pl->to_AO_basis(Gmat_so);
250 if (debug_>1) {
251 Gmat.print("Gmat in AO basis");
252 }
253 BlockedSymmSCMatrix *blocked_Gmat = dynamic_cast<BlockedSymmSCMatrix*>(Gmat.pointer());
254 if (!blocked_Gmat || blocked_Gmat->nblocks() != 1) {
255 ExEnv::outn() << "csgmat.cc: Gmat is wrong type" << std::endl;
256 abort();
257 }
258 Gmat = blocked_Gmat->block(0);
259
260 tim_exit("gmat");
261
262 return 0;
263}
264
265int
266MBPT2::make_cs_gmat(RefSymmSCMatrix& Gmat, double *DPmat)
267{
268 int errcod;
269
270 tim_enter("gmat");
271
272 errcod = make_g_d_nor(Gmat, DPmat, intbuf_);
273
274 if (errcod != 0) {
275 fprintf(stderr,"mbpt_gmat: trouble forming gmat 3\n");
276 return -1;
277 }
278
279 tim_exit("gmat");
280
281 return 0;
282}
283
284/************************************************************************
285 *
286 * Form the vector maxp; each element of maxp is the 2-based log of the
287 * largest element (absolute value) in a block of the density matrix
288 * (DPmat). The density matrix is of dimension nbasis x nbasis
289 *
290 ************************************************************************/
291
292void
293MBPT2::form_max_dens(double *DPmat, signed char *maxp)
294{
295
296 int i, j, k, l, ij;
297 int isize, jsize, ioffset, joffset;
298 double linv = 1.0/log(2.0);
299 double tol = pow(2.0,-126.0);
300 double ftmp, tmp;
301 double *dpmat_ptr;
302
303 for (i=0; i<basis()->nshell(); i++) {
304 isize = basis()->shell(i).nfunction();
305 ioffset = basis()->shell_to_function(i);
306 for (j=0; j<=i; j++) {
307 jsize = basis()->shell(j).nfunction();
308 joffset = basis()->shell_to_function(j);
309 tmp = 0.0;
310 for (k=0; k<isize; k++) {
311 dpmat_ptr = &DPmat[nbasis*(ioffset+k) + joffset];
312 for (l=0; l<jsize; l++) {
313 ftmp = fabs(*dpmat_ptr++);
314 if (ftmp > tmp) tmp = ftmp;
315 }
316 }
317 tmp = (tmp > tol) ? tmp : tol;
318 ij = i*(i+1)/2 +j;
319 maxp[ij] = (signed char) (log(tmp)*linv);
320 /* log(tmp)/linv equals the 2-based log of tmp */
321 }
322 }
323
324}
325
326int
327MBPT2::init_cs_gmat()
328{
329 tbint_ = integral()->electron_repulsion();
330 tbint_->set_redundant(0);
331 intbuf_ = tbint_->buffer();
332 return 1;
333}
334
335void
336MBPT2::done_cs_gmat()
337{
338 tbint_ = 0;
339 intbuf_ = 0;
340}
341
342int
343MBPT2::make_g_d_nor(RefSymmSCMatrix& Gmat,
344 double *DPmat, const double *mgdbuff)
345{
346 int tmax,imax,cpmax,pmaxijk=0;
347 int pmaxik,pmaxjk,pmaxij=0;
348 int i,j,k,l;
349 int ij,kl;
350 int n1,n2,n3,n4;
351 int e12,e34,e13e24,e_any;
352 int bf1,bf2,bf3,bf4;
353 int i1,j1,k1,l1;
354 int i2,j2,k2,l2;
355 int ii,jj,kk,ll;
356 int ij1;
357 int lij,lkl;
358 int index;
359 int int_index,kindex;
360 int nproc=msg_->n();
361 int me=msg_->me();
362 int s1,s2,s3,s4;
363 int nbatri = (nbasis*(nbasis+1))/2;
364
365 double tol = desired_gradient_accuracy() / 1000.0;
366 if (min_orthog_res() < 1.0) { tol *= min_orthog_res(); }
367 int inttol = (int) (log(tol)/log(2.0));
368
369 double tnint=0.0;
370 double pki_int,value;
371 double *gtmp=0, *ptmp=0;
372 double *dpmat_ptr;
373
374 char *shnfunc=0;
375 signed char *maxp=0;
376
377
378 // Scale DPmat; this is necessary when using the gmat formation
379 // program from scf (modified slightly), since this program assumes
380 // that the off-diagonal elements have been scaled by a factor of 2.0
381 dpmat_ptr = DPmat;
382 for (i=0; i<nbasis; i++) {
383 for (j=0; j<nbasis; j++) {
384 if (i != j) *dpmat_ptr++ *= 2.0;
385 else dpmat_ptr++;
386 }
387 }
388
389 // Allocate and assign maxp
390 if (eliminate_in_gmat_) {
391 int nshellt = basis()->nshell()*(basis()->nshell()+1)/2;
392 maxp = (signed char*) malloc(sizeof(signed char)*nshellt);
393 if (!(maxp)) {
394 fprintf(stderr,"mkgdlb: could not malloc maxp\n");
395 return -1;
396 }
397 form_max_dens(DPmat, maxp);
398 }
399
400 // Allocate and assign ptmp (contains lower triangle of DPmat
401 ptmp = (double*) malloc(sizeof(double)*nbatri);
402 if (!(ptmp)) {
403 fprintf(stderr,"mkgdlb: could not malloc ptmp\n");
404 return -1;
405 }
406 for (i=0; i<nbasis; i++) {
407 dpmat_ptr = &DPmat[i*nbasis];
408 for (j=0; j<=i; j++) {
409 ptmp[i*(i+1)/2 + j] = *dpmat_ptr++;
410 }
411 }
412
413
414 // "Unscale" DPmat to get the original DPmat
415 dpmat_ptr = DPmat;
416 for (i=0; i<nbasis; i++) {
417 for (j=0; j<nbasis; j++) {
418 if (i != j) *dpmat_ptr++ *= 0.50;
419 else dpmat_ptr++;
420 }
421 }
422
423 // Allocate and initialize gtmp
424 gtmp = (double *) malloc(sizeof(double)*nbatri);
425 for (i=0; i<nbatri; i++) gtmp[i] = 0.0;
426
427 // Allocate and assign shnfunc
428 shnfunc = (char *) malloc(basis()->nshell());
429 if (!shnfunc) {
430 fprintf(stderr,"make_g_d_lb: could not malloc shnfunc\n");
431 return -1;
432 }
433 for (i=0; i < basis()->nshell(); i++) shnfunc[i]=basis()->shell(i).nfunction();
434
435
436 /********************************************************
437 * Start the actual formation of the G matrix: *
438 * Loop over all shells, calculate a bunch of integrals *
439 * from each shell quartet, and stick those integrals *
440 * where they belong *
441 ********************************************************/
442
443
444 kindex=int_index=0;
445 for (i=0; i<basis()->nshell(); i++) {
446
447 for (j=0; j<=i; j++) {
448 ij = ioff(i)+j;
449 if(eliminate_in_gmat_) pmaxij=maxp[ij];
450
451 for (k=0; k<=i; k++,kindex++) {
452 if(kindex%nproc!=me) {
453 continue;
454 }
455
456 kl=ioff(k);
457 if(eliminate_in_gmat_) {
458 pmaxijk=pmaxij;
459 if((pmaxik=maxp[(ioff(i)+k)]-2)>pmaxijk) pmaxijk=pmaxik;
460 if((pmaxjk=maxp[IOFF(j,k)]-2)>pmaxijk) pmaxijk=pmaxjk;
461 }
462
463 for (l=0; l<=(k==i?j:k); l++) {
464
465 imax = (int) tbint_->log2_shell_bound(i,j,k,l);
466
467 if(eliminate_in_gmat_) {
468 cpmax = (maxp[kl]>pmaxijk) ? maxp[kl] : pmaxijk;
469 if((tmax=maxp[(ioff(i)+l)]-2)>cpmax) cpmax=tmax;
470 if((tmax=maxp[IOFF(j,l)]-2)>cpmax) cpmax=tmax;
471
472 if(cpmax+imax < inttol) {
473 kl++;
474 continue;
475 }
476 }
477
478 s1 = i; s2 = j; s3 = k; s4 = l;
479
480 tbint_->compute_shell(s1,s2,s3,s4);
481
482 n1 = shnfunc[s1];
483 n2 = shnfunc[s2];
484 n3 = shnfunc[s3];
485 n4 = shnfunc[s4];
486
487 // Shell equivalence information
488 e12 = (s2==s1);
489 e13e24 = (s3==s1) && (s4==s2);
490 e34 = (s4==s3);
491
492 index = 0;
493
494 e_any = (e12||e13e24||e34);
495 if(e_any) {
496 for (bf1=0; bf1<=INT_MAX1(n1) ; bf1++) {
497 i2 = basis()->shell_to_function(s1) + bf1;
498
499 for (bf2=0; bf2<=INT_MAX2(e12,bf1,n2) ; bf2++) {
500 j2 = basis()->shell_to_function(s2) + bf2;
501 if(i2>=j2) { i1=i2; j1=j2; }
502 else { i1=j2; j1=i2; }
503 ij1=ioff(i1)+j1;
504
505 for (bf3=0; bf3<=INT_MAX3(e13e24,bf1,n3) ; bf3++) {
506 k2 = basis()->shell_to_function(s3) + bf3;
507
508 for (bf4=0;bf4<=INT_MAX4(e13e24,e34,bf1,bf2,bf3,n4);bf4++){
509 if (fabs(mgdbuff[index])>1.0e-10) {
510 l2 = basis()->shell_to_function(s4) + bf4;
511
512 if(k2>=l2) { k1=k2; l1=l2; }
513 else { k1=l2; l1=k2; }
514
515 if(ij1 >= ioff(k1)+l1) {
516 ii = i1; jj = j1; kk = k1; ll = l1;
517 }
518 else {
519 ii = k1; jj = l1; kk = i1; ll = j1;
520 }
521
522 pki_int = mgdbuff[index];
523
524 if (jj == kk) {
525 if (ii == jj || kk == ll) {
526 lij=ioff(ii)+jj;
527 lkl=ioff(kk)+ll;
528 value=(lij==lkl)? 0.25*pki_int: 0.5*pki_int;
529 gtmp[lij] += ptmp[lkl]*value;
530 gtmp[lkl] += ptmp[lij]*value;
531 }
532 else {
533 lij=ioff(ii)+jj;
534 lkl=ioff(kk)+ll;
535 value=(lij==lkl)? 0.375*pki_int: 0.75*pki_int;
536 gtmp[lij] += ptmp[lkl]*value;
537 gtmp[lkl] += ptmp[lij]*value;
538
539 lij=ioff(ii)+ll;
540 lkl=IOFF(kk,jj);
541 value=(lij==lkl)? 0.25*pki_int: 0.5*pki_int;
542 gtmp[lij] -= ptmp[lkl]*value;
543 gtmp[lkl] -= ptmp[lij]*value;
544 }
545 }
546 else if (ii == kk || jj == ll) {
547 lij=ioff(ii)+jj;
548 lkl=ioff(kk)+ll;
549 value=(lij==lkl)? 0.375*pki_int: 0.75*pki_int;
550 gtmp[lij] += ptmp[lkl]*value;
551 gtmp[lkl] += ptmp[lij]*value;
552
553 lij=ioff(ii)+kk;
554 lkl=IOFF(jj,ll);
555 value=(lij==lkl)? 0.25*pki_int : 0.5*pki_int;
556 gtmp[lij] -= ptmp[lkl]*value;
557 gtmp[lkl] -= ptmp[lij]*value;
558 }
559 else {
560 lij=ioff(ii)+jj;
561 lkl=ioff(kk)+ll;
562 value=(lij==lkl)? 0.5*pki_int : pki_int;
563 gtmp[lij] += ptmp[lkl]*value;
564 gtmp[lkl] += ptmp[lij]*value;
565
566 lij=ioff(ii)+kk;
567 lkl=IOFF(jj,ll);
568 value=(lij==lkl)? 0.125*pki_int: 0.25*pki_int;
569 gtmp[lij] -= ptmp[lkl]*value;
570 gtmp[lkl] -= ptmp[lij]*value;
571
572 if((ii != jj) && (kk != ll)) {
573 lij=ioff(ii)+ll;
574 lkl=IOFF(kk,jj);
575 value=(lij==lkl)? 0.125*pki_int: 0.25*pki_int;
576 gtmp[lij] -= ptmp[lkl]*value;
577 gtmp[lkl] -= ptmp[lij]*value;
578 }
579 }
580 }
581 index++;
582 }
583 }
584 }
585 }
586 }
587 else {
588 for (bf1=0; bf1<n1 ; bf1++) {
589 i2 = basis()->shell_to_function(s1) + bf1;
590
591 for (bf2=0; bf2<n2 ; bf2++) {
592 j2 = basis()->shell_to_function(s2) + bf2;
593 if(i2>=j2) { i1=i2; j1=j2; }
594 else { i1=j2; j1=i2; }
595 ij1=ioff(i1)+j1;
596
597 for (bf3=0; bf3<n3 ; bf3++) {
598 k2 = basis()->shell_to_function(s3) + bf3;
599
600 for (bf4=0; bf4<n4; bf4++) {
601 if (fabs(mgdbuff[index])>1.0e-10) {
602 l2 = basis()->shell_to_function(s4) + bf4;
603
604 if(k2>=l2) { k1=k2; l1=l2; }
605 else { k1=l2; l1=k2; }
606
607 if(ij1 >= ioff(k1)+l1) {
608 ii = i1; jj = j1; kk = k1; ll = l1;
609 }
610 else {
611 ii = k1; jj = l1; kk = i1; ll = j1;
612 }
613
614 pki_int = mgdbuff[index];
615
616 if (jj == kk) {
617 lij=ioff(ii)+jj;
618 lkl=ioff(kk)+ll;
619 value=0.75*pki_int;
620 gtmp[lij] += ptmp[lkl]*value;
621 gtmp[lkl] += ptmp[lij]*value;
622
623 lij=ioff(ii)+ll;
624 lkl=IOFF(kk,jj);
625 value=0.5*pki_int;
626 gtmp[lij] -= ptmp[lkl]*value;
627 gtmp[lkl] -= ptmp[lij]*value;
628 }
629 else if (ii == kk || jj == ll) {
630 lij=ioff(ii)+jj;
631 lkl=ioff(kk)+ll;
632 value=0.75*pki_int;
633 gtmp[lij] += ptmp[lkl]*value;
634 gtmp[lkl] += ptmp[lij]*value;
635
636 lij=ioff(ii)+kk;
637 lkl=IOFF(jj,ll);
638 value=0.5*pki_int;
639 gtmp[lij] -= ptmp[lkl]*value;
640 gtmp[lkl] -= ptmp[lij]*value;
641 }
642 else {
643 lij=ioff(ii)+jj;
644 lkl=ioff(kk)+ll;
645 value=pki_int;
646 gtmp[lij] += ptmp[lkl]*value;
647 gtmp[lkl] += ptmp[lij]*value;
648
649 lij=ioff(ii)+kk;
650 lkl=IOFF(jj,ll);
651 value*=0.25;
652 gtmp[lij] -= ptmp[lkl]*value;
653 gtmp[lkl] -= ptmp[lij]*value;
654
655 lij=ioff(ii)+ll;
656 lkl=IOFF(kk,jj);
657 gtmp[lij] -= ptmp[lkl]*value;
658 gtmp[lkl] -= ptmp[lij]*value;
659 }
660 }
661 index++;
662 }
663 }
664 }
665 }
666 }
667 tnint += (double) (n1*n2*n3*n4);
668 kl++;
669 int_index++;
670 } // exit l loop
671 } // exit k loop
672 } // exit j loop
673 } // exit i loop
674
675 // Sum up contributions to gtmp
676 msg_->sum(gtmp,nbatri,ptmp);
677
678
679 // Put gtmp back into Gmat
680 for (i=0; i<nbasis; i++) {
681 for (j=0; j<=i; j++) {
682 ij = i*(i+1)/2 + j;
683 Gmat->set_element(i,j,gtmp[ij]);
684// Gmat->set_element(j,i,gtmp[ij]); don't do this - only lower triangle
685 }
686 }
687
688
689 // Free up memory
690 if (gtmp) free(gtmp);
691 if (maxp) free(maxp);
692 if (ptmp) free(ptmp);
693 if (shnfunc) free(shnfunc);
694
695 return 0;
696}
697
698////////////////////////////////////////////////////////////////////////////
699
700// Local Variables:
701// mode: c++
702// c-file-style: "CLJ-CONDENSED"
703// End:
Note: See TracBrowser for help on using the repository browser.