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
2829namespace ModuleESolver
2930{
3031
3132template <typename T, typename Device>
32- ESolver_KS<T, Device>::ESolver_KS()
33- {
34- }
33+ ESolver_KS<T, Device>::ESolver_KS(){}
3534
3635
3736template <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>
309292void 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