diff --git a/src/BOSampleStepper.C b/src/BOSampleStepper.C index ff24986..d79129c 100644 --- a/src/BOSampleStepper.C +++ b/src/BOSampleStepper.C @@ -740,8 +740,10 @@ void BOSampleStepper::step(int niter) mixer.restart(); double ehart, ehart_m; + bool scf_converged = false; + int itscf = 0; - for ( int itscf = 0; itscf < nitscf_; itscf++ ) + while ( !scf_converged && itscf < nitscf_ ) { if ( nite_ > 0 && onpe0 ) cout << " BOSampleStepper: start scf iteration" << endl; @@ -852,13 +854,17 @@ void BOSampleStepper::step(int niter) // if ( onpe0 && nite_ > 0 ) // cout << " delta_ehart = " << delta_ehart << endl; int ite = 0; - double etotal_int, etotal_int_m; - double eigenvalue_sum, eigenvalue_sum_m; + double etotal_int, etotal_int_m = 0.0; + double etotal, etotal_m = 0.0; + + double eigenvalue_sum, eigenvalue_sum_m = 0.0; // if nite == 0: do 1 iteration, no screening in charge mixing // if nite > 0: do nite iterations, use screening in charge mixing + // + double energy; while ( !nonscf_converged && ite < max(nite_,1) ) { - double energy = ef_.energy(true,dwf,false,fion,false,sigma_eks); + energy = ef_.energy(true,dwf,false,fion,false,sigma_eks); double enthalpy = energy; if ( ite > 0 ) @@ -930,6 +936,10 @@ void BOSampleStepper::step(int niter) ite++; } + if ( itscf > 0 ) + etotal_m = etotal; + etotal = energy; + // if ( onpe0 && nite_ > 0 && ite >= nite_ ) // cout << " BOSampleStepper::step: nscf loop not converged after " // << nite_ << " iterations" << endl; @@ -987,7 +997,11 @@ void BOSampleStepper::step(int niter) if ( nite_ > 0 && onpe0 ) cout << " BOSampleStepper: end scf iteration" << endl; - } // for itscf + + double delta_etotal = fabs(etotal - etotal_m); + scf_converged |= (delta_etotal < s_.ctrl.scf_tol); + itscf++; + } // while scf if ( compute_mlwf || compute_mlwfc ) { diff --git a/src/Control.h b/src/Control.h index e4a5dc4..aa6edec 100644 --- a/src/Control.h +++ b/src/Control.h @@ -66,5 +66,7 @@ struct Control int blHF[3]; double btHF; + + double scf_tol; }; #endif diff --git a/src/Makefile b/src/Makefile index 4c4ef3f..7c815c9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -533,7 +533,8 @@ qb.o: SlaterDet.h Basis.h Matrix.h AtomsDyn.h BlHF.h BtHF.h Cell.h CellDyn.h qb.o: CellLock.h CellMass.h ChargeMixCoeff.h ChargeMixNdim.h ChargeMixRcut.h qb.o: Debug.h Dspin.h Ecut.h Ecutprec.h Ecuts.h Emass.h ExtStress.h qb.o: FermiTemp.h Dt.h Nempty.h NetCharge.h Nrowmax.h Nspin.h RefCell.h -qb.o: Stress.h Thermostat.h ThTemp.h ThTime.h ThWidth.h WfDiag.h WfDyn.h Xc.h +qb.o: ScfTol.h Stress.h Thermostat.h ThTemp.h ThTime.h ThWidth.h WfDiag.h +qb.o: WfDyn.h Xc.h qbox_xmlns.o: qbox_xmlns.h QuitCmd.o: UserInterface.h Sample.h AtomSet.h Context.h Atom.h D3vector.h QuitCmd.o: UnitCell.h ConstraintSet.h ExtForceSet.h Wavefunction.h Control.h @@ -588,6 +589,8 @@ SaveCmd.o: D3vector.h UnitCell.h ConstraintSet.h ExtForceSet.h Wavefunction.h SaveCmd.o: Control.h SampleWriter.h isodate.h release.h SaveCmd.o: UserInterface.h Sample.h AtomSet.h Context.h Atom.h D3vector.h SaveCmd.o: UnitCell.h ConstraintSet.h ExtForceSet.h Wavefunction.h Control.h +ScfTol.o: Sample.h AtomSet.h Context.h Atom.h D3vector.h UnitCell.h +ScfTol.o: ConstraintSet.h ExtForceSet.h Wavefunction.h Control.h SDAIonicStepper.o: SDAIonicStepper.h IonicStepper.h Sample.h AtomSet.h SDAIonicStepper.o: Context.h Atom.h D3vector.h UnitCell.h ConstraintSet.h SDAIonicStepper.o: ExtForceSet.h Wavefunction.h Control.h Species.h @@ -659,8 +662,8 @@ testEnergyFunctional.o: UnitCell.h ConstraintSet.h ExtForceSet.h testEnergyFunctional.o: Wavefunction.h Control.h EnergyFunctional.h testEnergyFunctional.o: StructureFactor.h Timer.h test_fftw.o: Timer.h readTSC.h -testFourierTransform.o: Context.h Basis.h D3vector.h UnitCell.h -testFourierTransform.o: FourierTransform.h Timer.h +testFourierTransform.o: Basis.h D3vector.h UnitCell.h FourierTransform.h +testFourierTransform.o: Timer.h testjacobi.o: Timer.h Context.h Matrix.h jacobi.h testjade.o: Timer.h Context.h Matrix.h jade.h testLDAFunctional.o: LDAFunctional.h XCFunctional.h diff --git a/src/ScfTol.h b/src/ScfTol.h new file mode 100644 index 0000000..520e7c2 --- /dev/null +++ b/src/ScfTol.h @@ -0,0 +1,69 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2014 The Regents of the University of California +// +// This file is part of Qbox +// +// Qbox is distributed under the terms of the GNU General Public License +// as published by the Free Software Foundation, either version 2 of +// the License, or (at your option) any later version. +// See the file COPYING in the root directory of this distribution +// or . +// +//////////////////////////////////////////////////////////////////////////////// +// +// ScfTol.h +// +//////////////////////////////////////////////////////////////////////////////// +#ifndef SCFTOL_H +#define SCFTOL_H + +#include +#include +#include +#include + +#include "Sample.h" + +class ScfTol : public Var +{ + Sample *s; + + public: + + const char *name ( void ) const { return "scf_tol"; }; + + int set ( int argc, char **argv ) + { + if ( argc != 2 ) + { + if ( ui->onpe0() ) + cout << " scf_tol takes only one value" << endl; + return 1; + } + + double v = atof(argv[1]); + if ( v <= 0.0 ) + { + if ( ui->onpe0() ) + cout << " scf_tol must be non-negative" << endl; + return 1; + } + + s->ctrl.scf_tol = v; + return 0; + } + + string print (void) const + { + ostringstream st; + st.setf(ios::left,ios::adjustfield); + st << setw(10) << name() << " = "; + st.setf(ios::right,ios::adjustfield); + st << setw(10) << s->ctrl.scf_tol; + return st.str(); + } + + ScfTol(Sample *sample) : s(sample) { s->ctrl.scf_tol = 0.0; } +}; +#endif diff --git a/src/qb.C b/src/qb.C index 970f260..62fdba6 100644 --- a/src/qb.C +++ b/src/qb.C @@ -101,6 +101,7 @@ using namespace std; #include "Nrowmax.h" #include "Nspin.h" #include "RefCell.h" +#include "ScfTol.h" #include "Stress.h" #include "Thermostat.h" #include "ThTemp.h" @@ -310,6 +311,7 @@ int main(int argc, char **argv, char **envp) ui.addVar(new Nspin(s)); ui.addVar(new Dspin(s)); ui.addVar(new RefCell(s)); + ui.addVar(new ScfTol(s)); ui.addVar(new Stress(s)); ui.addVar(new Thermostat(s)); ui.addVar(new ThTemp(s));