source: ThirdParty/mpqc_open/src/lib/chemistry/qc/scf/scf.cc

Candidate_v1.6.1
Last change on this file 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.4 KB
RevLine 
[0b990d]1//
2// scf.cc --- implementation of the SCF abstract base class
3//
4// Copyright (C) 1996 Limit Point Systems, Inc.
5//
6// Author: Edward Seidl <seidl@janed.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#ifdef __GNUC__
29#pragma implementation
30#endif
31
32#include <math.h>
33#include <limits.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <unistd.h>
37
38#include <util/misc/formio.h>
39#include <util/state/stateio.h>
40#include <util/group/mstate.h>
41
42#include <math/scmat/local.h>
43#include <math/scmat/repl.h>
44#include <math/scmat/offset.h>
45#include <math/scmat/blocked.h>
46
47#include <math/optimize/diis.h>
48
49#include <chemistry/qc/basis/petite.h>
50#include <chemistry/qc/scf/scf.h>
51
52using namespace std;
53using namespace sc;
54
55///////////////////////////////////////////////////////////////////////////
56// SCF
57
58static ClassDesc SCF_cd(
59 typeid(SCF),"SCF",6,"public OneBodyWavefunction",
60 0, 0, 0);
61
62SCF::SCF(StateIn& s) :
63 SavableState(s),
64 OneBodyWavefunction(s)
65{
66 need_vec_ = 1;
67 compute_guess_ = 0;
68
69 s.get(maxiter_,"maxiter");
70 s.get(dens_reset_freq_);
71 s.get(reset_occ_);
72 s.get(local_dens_);
73 if (s.version(::class_desc<SCF>()) >= 3) {
74 double dstorage;
75 s.get(dstorage);
76 storage_ = size_t(dstorage);
77 }
78 else {
79 unsigned int istorage;
80 s.get(istorage);
81 storage_ = istorage;
82 }
83 if (s.version(::class_desc<SCF>()) >= 2) {
84 s.get(print_all_evals_);
85 s.get(print_occ_evals_);
86 }
87 else {
88 print_all_evals_ = 0;
89 print_occ_evals_ = 0;
90 }
91 s.get(level_shift_);
92 if (s.version(::class_desc<SCF>()) >= 5) {
93 s.get(keep_guess_wfn_);
94 guess_wfn_ << SavableState::restore_state(s);
95 }
96 else keep_guess_wfn_ = 0;
97 if (s.version(::class_desc<SCF>()) >= 6) {
98 s.get(always_use_guess_wfn_);
99 }
100 else always_use_guess_wfn_ = 0;
101
102 extrap_ << SavableState::restore_state(s);
103 accumdih_ << SavableState::restore_state(s);
104 accumddh_ << SavableState::restore_state(s);
105
106 scf_grp_ = basis()->matrixkit()->messagegrp();
107 threadgrp_ = ThreadGrp::get_default_threadgrp();
108}
109
110SCF::SCF(const Ref<KeyVal>& keyval) :
111 OneBodyWavefunction(keyval),
112 need_vec_(1),
113 compute_guess_(0),
114 maxiter_(100),
115 dens_reset_freq_(10),
116 reset_occ_(0),
117 local_dens_(1),
118 storage_(0),
119 level_shift_(0)
120{
121 if (keyval->exists("maxiter"))
122 maxiter_ = keyval->intvalue("maxiter");
123
124 if (keyval->exists("density_reset_frequency"))
125 dens_reset_freq_ = keyval->intvalue("density_reset_frequency");
126
127 if (keyval->exists("reset_occupations"))
128 reset_occ_ = keyval->booleanvalue("reset_occupations");
129
130 if (keyval->exists("level_shift"))
131 level_shift_ = keyval->doublevalue("level_shift");
132
133 extrap_ << keyval->describedclassvalue("extrap");
134 if (extrap_.null())
135 extrap_ = new DIIS;
136
137 accumdih_ << keyval->describedclassvalue("accumdih");
138 if (accumdih_.null())
139 accumdih_ = new AccumHNull;
140
141 accumddh_ << keyval->describedclassvalue("accumddh");
142 if (accumddh_.null())
143 accumddh_ = new AccumHNull;
144
145 KeyValValuesize defaultmem(DEFAULT_SC_MEMORY);
146 storage_ = keyval->sizevalue("memory",defaultmem);
147
148 if (keyval->exists("local_density"))
149 local_dens_ = keyval->booleanvalue("local_density");
150
151 print_all_evals_ = keyval->booleanvalue("print_evals");
152 print_occ_evals_ = keyval->booleanvalue("print_occupied_evals");
153
154 scf_grp_ = basis()->matrixkit()->messagegrp();
155 threadgrp_ = ThreadGrp::get_default_threadgrp();
156
157 keep_guess_wfn_ = keyval->booleanvalue("keep_guess_wavefunction");
158
159 always_use_guess_wfn_
160 = keyval->booleanvalue("always_use_guess_wavefunction");
161
162 // first see if guess_wavefunction is a wavefunction, then check to
163 // see if it's a string.
164 if (keyval->exists("guess_wavefunction")) {
165 ExEnv::out0() << incindent << incindent;
166 guess_wfn_ << keyval->describedclassvalue("guess_wavefunction");
167 compute_guess_=1;
168 if (guess_wfn_.null()) {
169 compute_guess_=0;
170 char *path = keyval->pcharvalue("guess_wavefunction");
171 struct stat sb;
172 if (path && stat(path, &sb)==0 && sb.st_size) {
173 BcastStateInBin s(scf_grp_, path);
174
175 // reset the default matrixkit so that the matrices in the guess
176 // wavefunction will match those in this wavefunction
177 Ref<SCMatrixKit> oldkit = SCMatrixKit::default_matrixkit();
178 SCMatrixKit::set_default_matrixkit(basis()->matrixkit());
179
180 guess_wfn_ << SavableState::restore_state(s);
181
182 // go back to the original default matrixkit
183 SCMatrixKit::set_default_matrixkit(oldkit);
184 delete[] path;
185 }
186 }
187 ExEnv::out0() << decindent << decindent;
188 }
189}
190
191SCF::~SCF()
192{
193}
194
195void
196SCF::save_data_state(StateOut& s)
197{
198 OneBodyWavefunction::save_data_state(s);
199 s.put(maxiter_);
200 s.put(dens_reset_freq_);
201 s.put(reset_occ_);
202 s.put(local_dens_);
203 double dstorage = storage_;
204 s.put(dstorage);
205 s.put(print_all_evals_);
206 s.put(print_occ_evals_);
207 s.put(level_shift_);
208 s.put(keep_guess_wfn_);
209 SavableState::save_state(guess_wfn_.pointer(),s);
210 s.put(always_use_guess_wfn_);
211 SavableState::save_state(extrap_.pointer(),s);
212 SavableState::save_state(accumdih_.pointer(),s);
213 SavableState::save_state(accumddh_.pointer(),s);
214}
215
216RefSCMatrix
217SCF::oso_eigenvectors()
218{
219 return oso_eigenvectors_.result();
220}
221
222RefDiagSCMatrix
223SCF::eigenvalues()
224{
225 return eigenvalues_.result();
226}
227
228int
229SCF::spin_unrestricted()
230{
231 return 0;
232}
233
234void
235SCF::symmetry_changed()
236{
237 OneBodyWavefunction::symmetry_changed();
238 if (guess_wfn_.nonnull()) {
239 guess_wfn_->symmetry_changed();
240 }
241}
242
243void
244SCF::print(ostream&o) const
245{
246 OneBodyWavefunction::print(o);
247 o << indent << "SCF Parameters:\n" << incindent
248 << indent << "maxiter = " << maxiter_ << endl
249 << indent << "density_reset_frequency = " << dens_reset_freq_ << endl
250 << indent << scprintf("level_shift = %f\n",level_shift_)
251 << decindent << endl;
252}
253
254//////////////////////////////////////////////////////////////////////////////
255
256void
257SCF::compute()
258{
259 local_ = (dynamic_cast<LocalSCMatrixKit*>(basis()->matrixkit().pointer()) ||
260 dynamic_cast<ReplSCMatrixKit*>(basis()->matrixkit().pointer())) ? 1:0;
261
262 const double hess_to_grad_acc = 1.0/100.0;
263 if (hessian_needed())
264 set_desired_gradient_accuracy(desired_hessian_accuracy()*hess_to_grad_acc);
265
266 const double grad_to_val_acc = 1.0/100.0;
267 if (gradient_needed())
268 set_desired_value_accuracy(desired_gradient_accuracy()*grad_to_val_acc);
269
270 double delta;
271 if (value_needed()) {
272 ExEnv::out0() << endl << indent
273 << scprintf("SCF::compute: energy accuracy = %10.7e\n",
274 desired_value_accuracy())
275 << endl;
276
277 // calculate the nuclear repulsion energy
278 double nucrep = nuclear_repulsion_energy();
279 ExEnv::out0() << indent
280 << scprintf("nuclear repulsion energy = %15.10f", nucrep)
281 << endl << endl;
282
283 double eelec;
284 delta = compute_vector(eelec,nucrep);
285
286 double eother = 0.0;
287 if (accumddh_.nonnull()) eother = accumddh_->e();
288 ExEnv::out0() << endl << indent
289 << scprintf("total scf energy = %15.10f", eelec+eother+nucrep)
290 << endl;
291
292 set_energy(eelec+eother+nucrep);
293 set_actual_value_accuracy(delta);
294 }
295 else {
296 delta = actual_value_accuracy();
297 }
298
299 if (gradient_needed()) {
300 RefSCVector gradient = matrixkit()->vector(moldim());
301
302 ExEnv::out0() << endl << indent
303 << scprintf("SCF::compute: gradient accuracy = %10.7e\n",
304 desired_gradient_accuracy())
305 << endl;
306
307 compute_gradient(gradient);
308 print_natom_3(gradient,"Total Gradient:");
309 set_gradient(gradient);
310
311 set_actual_gradient_accuracy(delta/grad_to_val_acc);
312 }
313
314 if (hessian_needed()) {
315 RefSymmSCMatrix hessian = matrixkit()->symmmatrix(moldim());
316
317 ExEnv::out0() << endl << indent
318 << scprintf("SCF::compute: hessian accuracy = %10.7e\n",
319 desired_hessian_accuracy())
320 << endl;
321
322 compute_hessian(hessian);
323 set_hessian(hessian);
324
325 set_actual_hessian_accuracy(delta/grad_to_val_acc/hess_to_grad_acc);
326 }
327}
328
329//////////////////////////////////////////////////////////////////////////////
330
331signed char *
332SCF::init_pmax(double *pmat_data)
333{
334 double l2inv = 1.0/log(2.0);
335 double tol = pow(2.0,-126.0);
336
337 GaussianBasisSet& gbs = *basis().pointer();
338
339 signed char * pmax = new signed char[i_offset(gbs.nshell())];
340
341 int ish, jsh, ij;
342 for (ish=ij=0; ish < gbs.nshell(); ish++) {
343 int istart = gbs.shell_to_function(ish);
344 int iend = istart + gbs(ish).nfunction();
345
346 for (jsh=0; jsh <= ish; jsh++,ij++) {
347 int jstart = gbs.shell_to_function(jsh);
348 int jend = jstart + gbs(jsh).nfunction();
349
350 double maxp=0, tmp;
351
352 for (int i=istart; i < iend; i++) {
353 int ijoff = i_offset(i) + jstart;
354 for (int j=jstart; j < ((ish==jsh) ? i+1 : jend); j++,ijoff++)
355 if ((tmp=fabs(pmat_data[ijoff])) > maxp)
356 maxp=tmp;
357 }
358
359 if (maxp <= tol)
360 maxp=tol;
361
362 long power = long(ceil(log(maxp)*l2inv));
363 if (power < SCHAR_MIN) pmax[ij] = SCHAR_MIN;
364 else if (power > SCHAR_MAX) pmax[ij] = SCHAR_MAX;
365 else pmax[ij] = (signed char) power;
366 }
367 }
368
369 return pmax;
370}
371
372//////////////////////////////////////////////////////////////////////////////
373
374RefSymmSCMatrix
375SCF::get_local_data(const RefSymmSCMatrix& m, double*& p, Access access)
376{
377 RefSymmSCMatrix l = m;
378
379 if (!dynamic_cast<LocalSymmSCMatrix*>(l.pointer())
380 && !dynamic_cast<ReplSymmSCMatrix*>(l.pointer())) {
381 Ref<SCMatrixKit> k = new ReplSCMatrixKit;
382 l = k->symmmatrix(m.dim());
383 l->convert(m);
384
385 if (access == Accum)
386 l->assign(0.0);
387 } else if (scf_grp_->n() > 1 && access==Accum) {
388 l = m.clone();
389 l.assign(0.0);
390 }
391
392 if (dynamic_cast<ReplSymmSCMatrix*>(l.pointer()))
393 p = dynamic_cast<ReplSymmSCMatrix*>(l.pointer())->get_data();
394 else
395 p = dynamic_cast<LocalSymmSCMatrix*>(l.pointer())->get_data();
396
397 return l;
398}
399
400//////////////////////////////////////////////////////////////////////////////
401
402void
403SCF::initial_vector(int needv)
404{
405 if (need_vec_) {
406 if (always_use_guess_wfn_ || oso_eigenvectors_.result_noupdate().null()) {
407 // if guess_wfn_ is non-null then try to get a guess vector from it.
408 // First check that the same basis is used...if not, then project the
409 // guess vector into the present basis.
410 if (guess_wfn_.nonnull()) {
411 if (basis()->equiv(guess_wfn_->basis())
412 &&orthog_method() == guess_wfn_->orthog_method()
413 &&oso_dimension()->equiv(guess_wfn_->oso_dimension().pointer())) {
414 ExEnv::out0() << indent
415 << "Using guess wavefunction as starting vector" << endl;
416
417 // indent output of eigenvectors() call if there is any
418 ExEnv::out0() << incindent << incindent;
419 SCF *g = dynamic_cast<SCF*>(guess_wfn_.pointer());
420 if (!g || compute_guess_) {
421 oso_eigenvectors_ = guess_wfn_->oso_eigenvectors().copy();
422 eigenvalues_ = guess_wfn_->eigenvalues().copy();
423 } else {
424 oso_eigenvectors_ = g->oso_eigenvectors_.result_noupdate().copy();
425 eigenvalues_ = g->eigenvalues_.result_noupdate().copy();
426 }
427 ExEnv::out0() << decindent << decindent;
428 } else {
429 ExEnv::out0() << indent
430 << "Projecting guess wavefunction into the present basis set"
431 << endl;
432
433 // indent output of projected_eigenvectors() call if there is any
434 ExEnv::out0() << incindent << incindent;
435 oso_eigenvectors_ = projected_eigenvectors(guess_wfn_);
436 eigenvalues_ = projected_eigenvalues(guess_wfn_);
437 ExEnv::out0() << decindent << decindent;
438 }
439
440 // we should only have to do this once, so free up memory used
441 // for the old wavefunction, unless told otherwise
442 if (!keep_guess_wfn_) guess_wfn_=0;
443
444 ExEnv::out0() << endl;
445
446 } else {
447 ExEnv::out0() << indent << "Starting from core Hamiltonian guess\n"
448 << endl;
449 oso_eigenvectors_ = hcore_guess(eigenvalues_.result_noupdate());
450 }
451 } else {
452 // this is just an old vector
453 }
454 }
455
456 need_vec_=needv;
457}
458
459//////////////////////////////////////////////////////////////////////////////
460
461void
462SCF::init_mem(int nm)
463{
464 // if local_den_ is already 0, then that means it was set to zero by
465 // the user.
466 if (!local_dens_) {
467 integral()->set_storage(storage_);
468 return;
469 }
470
471 size_t nmem = i_offset(basis()->nbasis())*nm*sizeof(double);
472
473 // if we're actually using local matrices, then there's no choice
474 if (dynamic_cast<LocalSCMatrixKit*>(basis()->matrixkit().pointer())
475 ||dynamic_cast<ReplSCMatrixKit*>(basis()->matrixkit().pointer())) {
476 if (nmem > storage_)
477 return;
478 } else {
479 if (nmem > storage_) {
480 local_dens_=0;
481 integral()->set_storage(storage_);
482 return;
483 }
484 }
485
486 integral()->set_storage(storage_-nmem);
487}
488
489/////////////////////////////////////////////////////////////////////////////
490
491void
492SCF::so_density(const RefSymmSCMatrix& d, double occ, int alp)
493{
494 int i,j,k;
495 int me=scf_grp_->me();
496 int nproc=scf_grp_->n();
497 int uhf = spin_unrestricted();
498
499 d->assign(0.0);
500
501 RefSCMatrix oso_vector;
502 if (alp || !uhf) {
503 if (oso_scf_vector_.nonnull())
504 oso_vector = oso_scf_vector_;
505 }
506 else {
507 if (oso_scf_vector_beta_.nonnull())
508 oso_vector = oso_scf_vector_beta_;
509 }
510
511 if (oso_vector.null()) {
512 if (uhf) {
513 if (alp)
514 oso_vector = oso_alpha_eigenvectors();
515 else
516 oso_vector = oso_beta_eigenvectors();
517 } else
518 oso_vector = oso_eigenvectors();
519 }
520
521 if (debug_ > 1) oso_vector.print("ortho SO vector");
522
523 RefSCMatrix vector = so_to_orthog_so().t() * oso_vector;
524 oso_vector = 0;
525
526 if (debug_ > 1) vector.print("SO vector");
527
528 BlockedSCMatrix *bvec = require_dynamic_cast<BlockedSCMatrix*>(
529 vector, "SCF::so_density: blocked vector");
530
531 BlockedSymmSCMatrix *bd = require_dynamic_cast<BlockedSymmSCMatrix*>(
532 d, "SCF::so_density: blocked density");
533
534 for (int ir=0; ir < oso_dimension()->blocks()->nblock(); ir++) {
535 RefSCMatrix vir = bvec->block(ir);
536 RefSymmSCMatrix dir = bd->block(ir);
537
538 if (vir.null() || vir.ncol()==0)
539 continue;
540
541 int n_orthoSO = oso_dimension()->blocks()->size(ir);
542 int n_SO = so_dimension()->blocks()->size(ir);
543
544 // figure out which columns of the scf vector we'll need
545 int col0 = -1, coln = -1;
546 for (i=0; i < n_orthoSO; i++) {
547 double occi;
548 if (!uhf)
549 occi = occupation(ir, i);
550 else if (alp)
551 occi = alpha_occupation(ir, i);
552 else
553 occi = beta_occupation(ir, i);
554
555 if (fabs(occi-occ) < 1.0e-8) {
556 if (col0 == -1)
557 col0 = i;
558 continue;
559 } else if (col0 != -1) {
560 coln = i-1;
561 break;
562 }
563 }
564
565 if (col0 == -1)
566 continue;
567
568 if (coln == -1)
569 coln = n_orthoSO-1;
570
571 if (local_ || local_dens_) {
572 RefSymmSCMatrix ldir = dir;
573
574 RefSCMatrix occbits; // holds the occupied bits of the scf vector
575
576 // get local copies of vector and density matrix
577 if (!local_) {
578 Ref<SCMatrixKit> rk = new ReplSCMatrixKit;
579 RefSCMatrix lvir = rk->matrix(vir.rowdim(), vir.coldim());
580 lvir->convert(vir);
581 occbits = lvir->get_subblock(0, n_SO-1, col0, coln);
582 lvir = 0;
583
584 ldir = rk->symmmatrix(dir.dim());
585 ldir->convert(dir);
586
587 } else {
588 occbits = vir->get_subblock(0, n_SO-1, col0, coln);
589 }
590
591 double **c;
592 double *dens;
593
594 if (dynamic_cast<LocalSCMatrix*>(occbits.pointer()))
595 c = dynamic_cast<LocalSCMatrix*>(occbits.pointer())->get_rows();
596 else if (dynamic_cast<ReplSCMatrix*>(occbits.pointer()))
597 c = dynamic_cast<ReplSCMatrix*>(occbits.pointer())->get_rows();
598 else
599 abort();
600
601 if (dynamic_cast<LocalSymmSCMatrix*>(ldir.pointer()))
602 dens = dynamic_cast<LocalSymmSCMatrix*>(ldir.pointer())->get_data();
603 else if (dynamic_cast<ReplSymmSCMatrix*>(ldir.pointer()))
604 dens = dynamic_cast<ReplSymmSCMatrix*>(ldir.pointer())->get_data();
605 else
606 abort();
607
608 int ij=0;
609 for (i=0; i < n_SO; i++) {
610 for (j=0; j <= i; j++, ij++) {
611 if (ij%nproc != me)
612 continue;
613
614 double dv = 0;
615
616 int kk=0;
617 for (k=col0; k <= coln; k++, kk++)
618 dv += c[i][kk]*c[j][kk];
619
620 dens[ij] = dv;
621 }
622 }
623
624 if (nproc > 1)
625 scf_grp_->sum(dens, i_offset(n_SO));
626
627 if (!local_) {
628 dir->convert(ldir);
629 }
630 }
631
632 // for now quit
633 else {
634 ExEnv::err0() << indent
635 << "Cannot yet use anything but Local matrices"
636 << endl;
637 abort();
638 }
639 }
640
641 if (debug_ > 0) {
642 ExEnv::out0() << indent
643 << "Nelectron = " << 2.0 * (d * overlap()).trace() << endl;
644 }
645
646 int use_alternate_density = 0;
647 if (use_alternate_density || debug_ > 2) {
648 // double check the density with this simpler, slower way to compute
649 // the density matrix
650 RefSymmSCMatrix occ(oso_dimension(), basis_matrixkit());
651 occ.assign(0.0);
652 for (i=0; i<oso_dimension()->n(); i++) {
653 occ(i,i) = occupation(i);
654 }
655 occ.scale(0.5);
656 RefSymmSCMatrix d2(so_dimension(), basis_matrixkit());
657 d2.assign(0.0);
658 d2.accumulate_transform(vector, occ);
659 if (debug_ > 2) {
660 d2.print("d2 density");
661 ExEnv::out0() << indent << "d2 Nelectron = "
662 << 2.0 * (d2 * overlap()).trace() << endl;
663 }
664 if (use_alternate_density) {
665 d.assign(d2);
666 ExEnv::out0() << indent
667 << "using alternate density algorithm" << endl;
668 }
669 }
670
671 if (debug_ > 1) {
672 d.print("SO Density");
673 RefSCMatrix rd(d.dim(), d.dim(), basis_matrixkit());
674 rd.assign(0.0);
675 rd.accumulate(d);
676 (d*overlap()*d-rd).print("SO Density idempotency error");
677 }
678}
679
680double
681SCF::one_body_energy()
682{
683 RefSymmSCMatrix dens = ao_density().copy();
684 RefSymmSCMatrix hcore = dens->clone();
685 hcore.assign(0.0);
686 Ref<SCElementOp> hcore_op = new OneBodyIntOp(integral()->hcore());
687 hcore.element_op(hcore_op);
688
689 dens->scale_diagonal(0.5);
690 SCElementScalarProduct *prod = new SCElementScalarProduct;
691 prod->reference();
692 Ref<SCElementOp2> op = prod;
693 hcore->element_op(prod, dens);
694 double e = prod->result();
695 op = 0;
696 prod->dereference();
697 delete prod;
698 return 2.0 * e;
699}
700
701void
702SCF::two_body_energy(double &ec, double &ex)
703{
704 ExEnv::errn() << class_name() << ": two_body_energy not implemented" << endl;
705}
706
707/////////////////////////////////////////////////////////////////////////////
708
709void
710SCF::init_threads()
711{
712 int nthread = threadgrp_->nthread();
713 size_t int_store = integral()->storage_unused()/nthread;
714
715 // initialize the two electron integral classes
716 tbis_ = new Ref<TwoBodyInt>[nthread];
717 for (int i=0; i < nthread; i++) {
718 tbis_[i] = integral()->electron_repulsion();
719 tbis_[i]->set_integral_storage(int_store);
720 }
721
722}
723
724void
725SCF::done_threads()
726{
727 for (int i=0; i < threadgrp_->nthread(); i++) tbis_[i] = 0;
728 delete[] tbis_;
729 tbis_ = 0;
730}
731
732int *
733SCF::read_occ(const Ref<KeyVal> &keyval, const char *name, int nirrep)
734{
735 int *occ = 0;
736 if (keyval->exists(name)) {
737 if (keyval->count(name) != nirrep) {
738 ExEnv::err0() << indent
739 << "ERROR: SCF: have " << nirrep << " irreps but "
740 << name << " vector is length " << keyval->count(name)
741 << endl;
742 abort();
743 }
744 occ = new int[nirrep];
745 for (int i=0; i<nirrep; i++) {
746 occ[i] = keyval->intvalue(name,i);
747 }
748 }
749 return occ;
750}
751
752void
753SCF::obsolete()
754{
755 OneBodyWavefunction::obsolete();
756 if (guess_wfn_.nonnull()) guess_wfn_->obsolete();
757}
758
759/////////////////////////////////////////////////////////////////////////////
760
761// Local Variables:
762// mode: c++
763// c-file-style: "ETS"
764// End:
Note: See TracBrowser for help on using the repository browser.