Skip to content

Commit 5da1df7

Browse files
authored
Refactor ESolver continues, I move charge mixing codes to module_charge (#6616)
* add update_pot in source_estate * split update_pot in rt-TDDFT into two functions, one is the original update_pot, which is replaced by update_pot function in estate, the other is save2 function used in after_iter * fix bugs * update * update esolver_ks * small updates * small bug fixed
1 parent 1a49431 commit 5da1df7

File tree

3 files changed

+180
-166
lines changed

3 files changed

+180
-166
lines changed

source/source_esolver/esolver_ks.cpp

Lines changed: 36 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@
2424
#include "source_io/json_output/output_info.h"
2525

2626
#include "source_estate/update_pot.h" // mohan add 20251016
27+
#include "source_estate/module_charge/chgmixing.h" // mohan add 20251018
2728

2829
namespace ModuleESolver
2930
{
3031

3132
template <typename T, typename Device>
32-
ESolver_KS<T, Device>::ESolver_KS()
33-
{
34-
}
33+
ESolver_KS<T, Device>::ESolver_KS(){}
3534

3635

3736
template <typename T, typename Device>
@@ -274,31 +273,15 @@ void ESolver_KS<T, Device>::iter_init(UnitCell& ucell, const int istep, const in
274273

275274
if (PARAM.inp.esolver_type == "ksdft")
276275
{
277-
diag_ethr = hsolver::set_diagethr_ks(PARAM.inp.basis_type,
278-
PARAM.inp.esolver_type,
279-
PARAM.inp.calculation,
280-
PARAM.inp.init_chg,
281-
PARAM.inp.precision,
282-
istep,
283-
iter,
284-
drho,
285-
PARAM.inp.pw_diag_thr,
286-
diag_ethr,
287-
PARAM.inp.nelec);
276+
diag_ethr = hsolver::set_diagethr_ks(PARAM.inp.basis_type, PARAM.inp.esolver_type,
277+
PARAM.inp.calculation, PARAM.inp.init_chg, PARAM.inp.precision, istep, iter,
278+
drho, PARAM.inp.pw_diag_thr, diag_ethr, PARAM.inp.nelec);
288279
}
289280
else if (PARAM.inp.esolver_type == "sdft")
290281
{
291-
diag_ethr = hsolver::set_diagethr_sdft(PARAM.inp.basis_type,
292-
PARAM.inp.esolver_type,
293-
PARAM.inp.calculation,
294-
PARAM.inp.init_chg,
295-
istep,
296-
iter,
297-
drho,
298-
PARAM.inp.pw_diag_thr,
299-
diag_ethr,
300-
PARAM.inp.nbands,
301-
esolver_KS_ne);
282+
diag_ethr = hsolver::set_diagethr_sdft(PARAM.inp.basis_type, PARAM.inp.esolver_type,
283+
PARAM.inp.calculation, PARAM.inp.init_chg, istep, iter, drho,
284+
PARAM.inp.pw_diag_thr, diag_ethr, PARAM.inp.nbands, esolver_KS_ne);
302285
}
303286

304287
// save input charge density (rho)
@@ -309,9 +292,7 @@ template <typename T, typename Device>
309292
void ESolver_KS<T, Device>::iter_finish(UnitCell& ucell, const int istep, int& iter, bool &conv_esolver)
310293
{
311294

312-
//----------------------------------------------------------------
313-
// 1) print out band gap
314-
//----------------------------------------------------------------
295+
// 1.1) print out band gap
315296
if (!PARAM.globalv.two_fermi)
316297
{
317298
this->pelec->cal_bandgap();
@@ -321,125 +302,30 @@ void ESolver_KS<T, Device>::iter_finish(UnitCell& ucell, const int istep, int& i
321302
this->pelec->cal_bandgap_updw();
322303
}
323304

305+
// 1.2) print out eigenvalues and occupations
324306
if(iter % PARAM.inp.out_freq_elec == 0)
325307
{
326-
//----------------------------------------------------------------
327-
// 2) print out eigenvalues and occupations
328-
//----------------------------------------------------------------
329308
if (PARAM.inp.out_band[0] || iter == PARAM.inp.scf_nmax || conv_esolver)
330309
{
331310
ModuleIO::write_eig_iter(this->pelec->ekb,this->pelec->wg,*this->pelec->klist);
332311
}
333312
}
334313

335-
//----------------------------------------------------------------
336-
// 2) compute magnetization, only for LSDA(spin==2)
337-
//----------------------------------------------------------------
314+
// 2.1) compute magnetization, only for spin==2
338315
ucell.magnet.compute_mag(ucell.omega, this->chr.nrxx, this->chr.nxyz, this->chr.rho,
339316
this->pelec->nelec_spin.data());
340317

341-
//----------------------------------------------------------------
342-
// 3) charge mixing
343-
//----------------------------------------------------------------
344-
if (PARAM.globalv.ks_run)
345-
{
346-
// mixing will restart at this->p_chgmix->mixing_restart steps
347-
if (drho <= PARAM.inp.mixing_restart && PARAM.inp.mixing_restart > 0.0
348-
&& this->p_chgmix->mixing_restart_step > iter)
349-
{
350-
this->p_chgmix->mixing_restart_step = iter + 1;
351-
}
352-
353-
if (PARAM.inp.scf_os_stop) // if oscillation is detected, SCF will stop
354-
{
355-
this->oscillate_esolver
356-
= this->p_chgmix->if_scf_oscillate(iter, drho, PARAM.inp.scf_os_ndim, PARAM.inp.scf_os_thr);
357-
}
358-
359-
// drho will be 0 at this->p_chgmix->mixing_restart step, which is
360-
// not ground state
361-
bool not_restart_step = !(iter == this->p_chgmix->mixing_restart_step && PARAM.inp.mixing_restart > 0.0);
362-
// SCF will continue if U is not converged for uramping calculation
363-
bool is_U_converged = true;
364-
// to avoid unnecessary dependence on dft+u, refactor is needed
365-
#ifdef __LCAO
366-
if (PARAM.inp.dft_plus_u)
367-
{
368-
is_U_converged = GlobalC::dftu.u_converged();
369-
}
370-
#endif
371-
372-
conv_esolver = (drho < this->scf_thr && not_restart_step && is_U_converged);
373-
374-
// add energy threshold for SCF convergence
375-
if (this->scf_ene_thr > 0.0)
376-
{
377-
// calculate energy of output charge density
378-
elecstate::update_pot(ucell, this->pelec, this->chr, conv_esolver);
379-
this->pelec->cal_energies(2); // 2 means Kohn-Sham functional
380-
// now, etot_old is the energy of input density, while etot is the energy of output density
381-
this->pelec->f_en.etot_delta = this->pelec->f_en.etot - this->pelec->f_en.etot_old;
382-
// output etot_delta
383-
GlobalV::ofs_running << " DeltaE_womix = " << this->pelec->f_en.etot_delta * ModuleBase::Ry_to_eV << " eV"
384-
<< std::endl;
385-
if (iter > 1 && conv_esolver == 1) // only check when density is converged
386-
{
387-
// update the convergence flag
388-
conv_esolver
389-
= (std::abs(this->pelec->f_en.etot_delta * ModuleBase::Ry_to_eV) < this->scf_ene_thr);
390-
}
391-
}
318+
// 2.2) charge mixing
319+
module_charge::chgmixing_ks(iter, ucell, this->pelec, this->chr, this->p_chgmix,
320+
this->pw_rhod->nrxx, this->drho, this->oscillate_esolver, conv_esolver, hsolver_error,
321+
this->scf_thr, this->scf_ene_thr, PARAM.inp);
392322

393-
// If drho < hsolver_error in the first iter or drho < scf_thr, we
394-
// do not change rho.
395-
if (drho < hsolver_error || conv_esolver || PARAM.inp.calculation == "nscf")
396-
{
397-
if (drho < hsolver_error)
398-
{
399-
GlobalV::ofs_warning << " drho < hsolver_error, keep "
400-
"charge density unchanged."
401-
<< std::endl;
402-
}
403-
}
404-
else
405-
{
406-
//----------charge mixing---------------
407-
// mixing will restart after this->p_chgmix->mixing_restart
408-
// steps
409-
if (PARAM.inp.mixing_restart > 0 && iter == this->p_chgmix->mixing_restart_step - 1
410-
&& drho <= PARAM.inp.mixing_restart)
411-
{
412-
// do not mix charge density
413-
}
414-
else
415-
{
416-
p_chgmix->mix_rho(&this->chr); // update chr->rho by mixing
417-
}
418-
if (PARAM.inp.scf_thr_type == 2)
419-
{
420-
this->chr.renormalize_rho(); // renormalize rho in R-space would
421-
// induce a error in K-space
422-
}
423-
//----------charge mixing done-----------
424-
}
425-
}
426-
427-
#ifdef __MPI
428-
MPI_Bcast(&drho, 1, MPI_DOUBLE, 0, BP_WORLD);
429-
430-
// change MPI_DOUBLE to MPI_C_BOOL, mohan 2025-04-13
431-
MPI_Bcast(&conv_esolver, 1, MPI_C_BOOL, 0, BP_WORLD);
432-
MPI_Bcast(this->chr.rho[0], this->pw_rhod->nrxx, MPI_DOUBLE, 0, BP_WORLD);
433-
#endif
434-
435-
// 4) Update potentials (should be done every SF iter)
323+
// 2.3) Update potentials (should be done every SF iter)
436324
elecstate::update_pot(ucell, this->pelec, this->chr, conv_esolver);
437325

438-
// 5) calculate energies
439-
// 1 means Harris-Foulkes functional
440-
// 2 means Kohn-Sham functional
441-
this->pelec->cal_energies(1);
442-
this->pelec->cal_energies(2);
326+
// 3.1) calculate energies
327+
this->pelec->cal_energies(1); // Harris-Foulkes functional
328+
this->pelec->cal_energies(2); // Kohn-Sham functional
443329

444330
if (iter == 1)
445331
{
@@ -448,10 +334,18 @@ void ESolver_KS<T, Device>::iter_finish(UnitCell& ucell, const int istep, int& i
448334
this->pelec->f_en.etot_delta = this->pelec->f_en.etot - this->pelec->f_en.etot_old;
449335
this->pelec->f_en.etot_old = this->pelec->f_en.etot;
450336

337+
// 4) get meta-GGA related parameters
338+
double dkin = 0.0; // for meta-GGA
339+
if (XC_Functional::get_ked_flag())
340+
{
341+
dkin = p_chgmix->get_dkin(&this->chr, PARAM.inp.nelec);
342+
}
451343

452-
//----------------------------------------------------------------
453-
// 6) time and meta-GGA
454-
//----------------------------------------------------------------
344+
// Iter finish
345+
ESolver_FP::iter_finish(ucell, istep, iter, conv_esolver);
346+
347+
348+
// the end, print time
455349
#ifdef __MPI
456350
double duration = (double)(MPI_Wtime() - iter_time);
457351
#else
@@ -460,38 +354,19 @@ void ESolver_KS<T, Device>::iter_finish(UnitCell& ucell, const int istep, int& i
460354
/ static_cast<double>(1e6);
461355
#endif
462356

463-
// get mtaGGA related parameters
464-
double dkin = 0.0; // for meta-GGA
465-
if (XC_Functional::get_ked_flag())
466-
{
467-
dkin = p_chgmix->get_dkin(&this->chr, PARAM.inp.nelec);
468-
}
469-
470-
// pint energy
471-
elecstate::print_etot(ucell.magnet, *pelec,conv_esolver, iter, drho,
357+
// print energies
358+
elecstate::print_etot(ucell.magnet, *pelec, conv_esolver, iter, drho,
472359
dkin, duration, diag_ethr);
473360

474361

475362
#ifdef __RAPIDJSON
476-
// 7) add Json of scf mag
363+
// add Json of scf mag
477364
Json::add_output_scf_mag(ucell.magnet.tot_mag, ucell.magnet.abs_mag,
478365
this->pelec->f_en.etot * ModuleBase::Ry_to_eV,
479366
this->pelec->f_en.etot_delta * ModuleBase::Ry_to_eV,
480367
drho, duration);
481368
#endif //__RAPIDJSON
482369

483-
484-
// 7) SCF restart information
485-
if (PARAM.inp.mixing_restart > 0
486-
&& iter == this->p_chgmix->mixing_restart_step - 1
487-
&& iter != PARAM.inp.scf_nmax)
488-
{
489-
this->p_chgmix->mixing_restart_last = iter;
490-
std::cout << " SCF restart after this step!" << std::endl;
491-
}
492-
493-
// 8) Iter finish
494-
ESolver_FP::iter_finish(ucell, istep, iter, conv_esolver);
495370
}
496371

497372
//! Something to do after SCF iterations when SCF is converged or comes to the max iter step.
@@ -534,13 +409,9 @@ void ESolver_KS<T, Device>::after_scf(UnitCell& ucell, const int istep, const bo
534409
ss << ".txt";
535410

536411
const double eshift = 0.0;
537-
ModuleIO::nscf_band(is,
538-
ss.str(),
539-
PARAM.inp.nbands,
540-
eshift,
541-
PARAM.inp.out_band[1], // precision
542-
this->pelec->ekb,
543-
this->kv);
412+
ModuleIO::nscf_band(is, ss.str(), PARAM.inp.nbands,
413+
eshift, PARAM.inp.out_band[1], // precision
414+
this->pelec->ekb, this->kv);
544415
}
545416
}
546417
}

0 commit comments

Comments
 (0)