1616#include " module_base/scalapack_connector.h"
1717#include " module_parameter/parameter.h"
1818#include " module_lr/ri_benchmark/ri_benchmark.h"
19+ #include " module_lr/operator_casida/operator_lr_diag.h" // for precondition
1920
2021#ifdef __EXX
2122template <>
@@ -444,20 +445,29 @@ void LR::ESolver_LR<T, TR>::runner(int istep, UnitCell& cell)
444445 if (GlobalV::MY_RANK == 0 ) { assert (nst == LR_Util::write_value (efile (label), prec, e, nst)); }
445446 assert (nst * dim == LR_Util::write_value (vfile (label), prec, v, nst, dim));
446447 };
448+ std::vector<double > precondition (this ->input .lr_solver == " lapack" ? 0 : nloc_per_band, 1.0 );
447449 // allocate and initialize A matrix and density matrix
448450 if (openshell)
449451 {
452+ for (int is : {0 , 1 })
453+ {
454+ const int offset_is = is * this ->paraX_ [0 ].get_local_size ();
455+ OperatorLRDiag<double > pre_op (this ->eig_ks .c + is * nk * (nocc[0 ] + nvirt[0 ]), this ->paraX_ [is], this ->nk , this ->nocc [is], this ->nvirt [is]);
456+ if (input.lr_solver != " lapack" ) { pre_op.act (1 , offset_is, 1 , precondition.data () + offset_is, precondition.data () + offset_is); }
457+ }
450458 std::cout << " Solving spin-conserving excitation for open-shell system." << std::endl;
451459 HamiltULR<T> hulr (xc_kernel, nspin, this ->nbasis , this ->nocc , this ->nvirt , this ->ucell , orb_cutoff_, GlobalC::GridD, *this ->psi_ks , this ->eig_ks ,
452460#ifdef __EXX
453461 this ->exx_lri , this ->exx_info .info_global .hybrid_alpha ,
454462#endif
455463 this ->gint_ , this ->pot , this ->kv , this ->paraX_ , this ->paraC_ , this ->paraMat_ );
456- LR::HSolver::solve (hulr, this ->X [0 ].template data <T>(), nloc_per_band, nstates, this ->pelec ->ekb .c , this ->input .lr_solver , this ->input .lr_thr );
464+ LR::HSolver::solve (hulr, this ->X [0 ].template data <T>(), nloc_per_band, nstates, this ->pelec ->ekb .c , this ->input .lr_solver , this ->input .lr_thr , precondition );
457465 if (input.out_wfc_lr ) { write_states (" openshell" , this ->pelec ->ekb .c , this ->X [0 ].template data <T>(), nloc_per_band, nstates); }
458466 }
459467 else
460468 {
469+ OperatorLRDiag<double > pre_op (this ->eig_ks .c , this ->paraX_ [0 ], this ->nk , this ->nocc [0 ], this ->nvirt [0 ]);
470+ if (input.lr_solver != " lapack" ) { pre_op.act (1 , nloc_per_band, 1 , precondition.data (), precondition.data ()); }
461471 auto spin_types = std::vector<std::string>({ " singlet" , " triplet" });
462472 for (int is = 0 ;is < nspin;++is)
463473 {
@@ -470,7 +480,7 @@ void LR::ESolver_LR<T, TR>::runner(int istep, UnitCell& cell)
470480 spin_types[is], input.ri_hartree_benchmark , (input.ri_hartree_benchmark == " aims" ? input.aims_nbasis : std::vector<int >({})));
471481 // solve the Casida equation
472482 LR::HSolver::solve (hlr, this ->X [is].template data <T>(), nloc_per_band, nstates,
473- this ->pelec ->ekb .c + is * nstates, this ->input .lr_solver , this ->input .lr_thr /* ,
483+ this ->pelec ->ekb .c + is * nstates, this ->input .lr_solver , this ->input .lr_thr , precondition /* ,
474484 !std::set<std::string>({ "hf", "hse" }).count(this->xc_kernel)*/ ); // whether the kernel is Hermitian
475485 if (input.out_wfc_lr ) { write_states (spin_types[is], this ->pelec ->ekb .c + is * nstates, this ->X [is].template data <T>(), nloc_per_band, nstates); }
476486 }
0 commit comments