@@ -114,6 +114,31 @@ void Charge_Mixing::set_mixing(const std::string& mixing_mode_in,
114114 return ;
115115}
116116
117+ void Charge_Mixing::allocate_mixing_dmr (int nnr)
118+ {
119+ // Note that: we cannot allocate memory for dmr_mdata in set_mixing.
120+ // since the size of dmr_mdata is given by the size of HContainer.nnr, which is calculated in DensityMatrix::init_DMR().
121+ // and DensityMatrix::init_DMR() is called in beforescf(). While set_mixing() is called in ESolver_KS::Init().
122+ ModuleBase::TITLE (" Charge_Mixing" , " allocate_mixing_dmr" );
123+ ModuleBase::timer::tick (" Charge_Mixing" , " allocate_mixing_dmr" );
124+ //
125+ const int dmr_nspin = (GlobalV::NSPIN == 2 ) ? 2 : 1 ;
126+ // allocate memory for dmr_mdata
127+ if (GlobalV::SCF_THR_TYPE == 1 )
128+ {
129+ ModuleBase::WARNING_QUIT (" Charge_Mixing" , " This Mixing of Density Matrix is not supported for PW basis yet" );
130+ }
131+ else if (GlobalV::SCF_THR_TYPE == 2 )
132+ {
133+ this ->mixing ->init_mixing_data (this ->dmr_mdata , nnr * dmr_nspin, sizeof (double ));
134+ }
135+
136+ this ->dmr_mdata .reset ();
137+ ModuleBase::timer::tick (" Charge_Mixing" , " allocate_mixing_dmr" );
138+
139+ return ;
140+ }
141+
117142void Charge_Mixing::set_rhopw (ModulePW::PW_Basis* rhopw_in, ModulePW::PW_Basis* rhodpw_in)
118143{
119144 this ->rhopw = rhopw_in;
@@ -737,6 +762,204 @@ void Charge_Mixing::mix_rho_real(Charge* chr)
737762
738763}
739764
765+ void Charge_Mixing::mix_dmr (elecstate::DensityMatrix<double , double >* DM)
766+ {
767+ // Notice that DensityMatrix object is a Template class
768+ ModuleBase::TITLE (" Charge_Mixing" , " mix_dmr" );
769+ ModuleBase::timer::tick (" Charge_Mixing" , " mix_dmr" );
770+ //
771+ std::vector<hamilt::HContainer<double >*> dmr = DM->get_DMR_vector ();
772+ std::vector<std::vector<double >> dmr_save = DM->get_DMR_save ();
773+ //
774+ // const int dmr_nspin = (GlobalV::NSPIN == 2) ? 2 : 1;
775+ double * dmr_in;
776+ double * dmr_out;
777+ if (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 4 )
778+ {
779+ dmr_in = dmr_save[0 ].data ();
780+ dmr_out = dmr[0 ]->get_wrapper ();
781+ this ->mixing ->push_data (this ->dmr_mdata , dmr_in, dmr_out, nullptr , false );
782+ this ->mixing ->mix_data (this ->dmr_mdata , dmr_out);
783+ }
784+ else if (GlobalV::NSPIN == 2 )
785+ {
786+ // magnetic density matrix
787+ double * dmr_mag = nullptr ;
788+ double * dmr_mag_save = nullptr ;
789+ const int nnr = dmr[0 ]->get_nnr ();
790+ // allocate dmr_mag[is*nnrx] and dmr_mag_save[is*nnrx]
791+ dmr_mag = new double [nnr * GlobalV::NSPIN];
792+ dmr_mag_save = new double [nnr * GlobalV::NSPIN];
793+ ModuleBase::GlobalFunc::ZEROS (dmr_mag, nnr * GlobalV::NSPIN);
794+ ModuleBase::GlobalFunc::ZEROS (dmr_mag_save, nnr * GlobalV::NSPIN);
795+ double * dmr_up;
796+ double * dmr_down;
797+ // tranfer dmr into dmr_mag
798+ dmr_up = dmr[0 ]->get_wrapper ();
799+ dmr_down = dmr[1 ]->get_wrapper ();
800+ for (int ir = 0 ; ir < nnr; ir++)
801+ {
802+ dmr_mag[ir] = dmr_up[ir] + dmr_down[ir];
803+ dmr_mag[ir + nnr] = dmr_up[ir] - dmr_down[ir];
804+ }
805+ // tranfer dmr_save into dmr_mag_save
806+ dmr_up = dmr_save[0 ].data ();
807+ dmr_down = dmr_save[1 ].data ();
808+ for (int ir = 0 ; ir < nnr; ir++)
809+ {
810+ dmr_mag_save[ir] = dmr_up[ir] + dmr_down[ir];
811+ dmr_mag_save[ir + nnr] = dmr_up[ir] - dmr_down[ir];
812+ }
813+ //
814+ dmr_in = dmr_mag_save;
815+ dmr_out = dmr_mag;
816+ // no kerker in mixing_dmr
817+ // auto screen = std::bind(&Charge_Mixing::Kerker_screen_real, this, std::placeholders::_1);
818+ auto twobeta_mix
819+ = [this , nnr](double * out, const double * in, const double * sres) {
820+ #ifdef _OPENMP
821+ #pragma omp parallel for schedule(static, 256)
822+ #endif
823+ for (int i = 0 ; i < nnr; ++i)
824+ {
825+ out[i] = in[i] + this ->mixing_beta * sres[i];
826+ }
827+ // magnetism
828+ #ifdef _OPENMP
829+ #pragma omp parallel for schedule(static, 256)
830+ #endif
831+ for (int i = nnr; i < 2 * nnr; ++i)
832+ {
833+ out[i] = in[i] + this ->mixing_beta_mag * sres[i];
834+ }
835+ };
836+ this ->mixing ->push_data (this ->dmr_mdata , dmr_in, dmr_out, nullptr , twobeta_mix, false );
837+ // auto inner_product
838+ // = std::bind(&Charge_Mixing::inner_product_real, this, std::placeholders::_1, std::placeholders::_2);
839+ // this->mixing->cal_coef(this->rho_mdata, inner_product);
840+ this ->mixing ->mix_data (this ->dmr_mdata , dmr_out);
841+ // get new dmr from dmr_mag
842+ dmr_up = dmr[0 ]->get_wrapper ();
843+ dmr_down = dmr[1 ]->get_wrapper ();
844+ for (int is = 0 ; is < GlobalV::NSPIN; is++)
845+ {
846+ ModuleBase::GlobalFunc::ZEROS (dmr_up, nnr);
847+ ModuleBase::GlobalFunc::ZEROS (dmr_down, nnr);
848+ }
849+ for (int ir = 0 ; ir < nnr; ir++)
850+ {
851+ dmr_up[ir] = 0.5 * (dmr_mag[ir] + dmr_mag[ir+nnr]);
852+ dmr_down[ir] = 0.5 * (dmr_mag[ir] - dmr_mag[ir+nnr]);
853+ }
854+ // delete
855+ delete[] dmr_mag;
856+ delete[] dmr_mag_save;
857+ }
858+
859+ ModuleBase::timer::tick (" Charge_Mixing" , " mix_dmr" );
860+
861+ return ;
862+ }
863+
864+ void Charge_Mixing::mix_dmr (elecstate::DensityMatrix<std::complex <double >, double >* DM)
865+ {
866+ // Notice that DensityMatrix object is a Template class
867+ ModuleBase::TITLE (" Charge_Mixing" , " mix_dmr" );
868+ ModuleBase::timer::tick (" Charge_Mixing" , " mix_dmr" );
869+ //
870+ std::vector<hamilt::HContainer<double >*> dmr = DM->get_DMR_vector ();
871+ std::vector<std::vector<double >> dmr_save = DM->get_DMR_save ();
872+ //
873+ // const int dmr_nspin = (GlobalV::NSPIN == 2) ? 2 : 1;
874+ double * dmr_in;
875+ double * dmr_out;
876+ if (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 4 )
877+ {
878+ dmr_in = dmr_save[0 ].data ();
879+ dmr_out = dmr[0 ]->get_wrapper ();
880+ this ->mixing ->push_data (this ->dmr_mdata , dmr_in, dmr_out, nullptr , false );
881+ this ->mixing ->mix_data (this ->dmr_mdata , dmr_out);
882+ }
883+ else if (GlobalV::NSPIN == 2 )
884+ {
885+ // magnetic density matrix
886+ double * dmr_mag = nullptr ;
887+ double * dmr_mag_save = nullptr ;
888+ const int nnr = dmr[0 ]->get_nnr ();
889+ // allocate dmr_mag[is*nnrx] and dmr_mag_save[is*nnrx]
890+ dmr_mag = new double [nnr * GlobalV::NSPIN];
891+ dmr_mag_save = new double [nnr * GlobalV::NSPIN];
892+ ModuleBase::GlobalFunc::ZEROS (dmr_mag, nnr * GlobalV::NSPIN);
893+ ModuleBase::GlobalFunc::ZEROS (dmr_mag_save, nnr * GlobalV::NSPIN);
894+ double * dmr_up;
895+ double * dmr_down;
896+ // tranfer dmr into dmr_mag
897+ dmr_up = dmr[0 ]->get_wrapper ();
898+ dmr_down = dmr[1 ]->get_wrapper ();
899+ for (int ir = 0 ; ir < nnr; ir++)
900+ {
901+ dmr_mag[ir] = dmr_up[ir] + dmr_down[ir];
902+ dmr_mag[ir + nnr] = dmr_up[ir] - dmr_down[ir];
903+ }
904+ // tranfer dmr_save into dmr_mag_save
905+ dmr_up = dmr_save[0 ].data ();
906+ dmr_down = dmr_save[1 ].data ();
907+ for (int ir = 0 ; ir < nnr; ir++)
908+ {
909+ dmr_mag_save[ir] = dmr_up[ir] + dmr_down[ir];
910+ dmr_mag_save[ir + nnr] = dmr_up[ir] - dmr_down[ir];
911+ }
912+ //
913+ dmr_in = dmr_mag_save;
914+ dmr_out = dmr_mag;
915+ // no kerker in mixing_dmr
916+ // auto screen = std::bind(&Charge_Mixing::Kerker_screen_real, this, std::placeholders::_1);
917+ auto twobeta_mix
918+ = [this , nnr](double * out, const double * in, const double * sres) {
919+ #ifdef _OPENMP
920+ #pragma omp parallel for schedule(static, 256)
921+ #endif
922+ for (int i = 0 ; i < nnr; ++i)
923+ {
924+ out[i] = in[i] + this ->mixing_beta * sres[i];
925+ }
926+ // magnetism
927+ #ifdef _OPENMP
928+ #pragma omp parallel for schedule(static, 256)
929+ #endif
930+ for (int i = nnr; i < 2 * nnr; ++i)
931+ {
932+ out[i] = in[i] + this ->mixing_beta_mag * sres[i];
933+ }
934+ };
935+ this ->mixing ->push_data (this ->dmr_mdata , dmr_in, dmr_out, nullptr , twobeta_mix, false );
936+ // auto inner_product
937+ // = std::bind(&Charge_Mixing::inner_product_real, this, std::placeholders::_1, std::placeholders::_2);
938+ // this->mixing->cal_coef(this->rho_mdata, inner_product);
939+ this ->mixing ->mix_data (this ->dmr_mdata , dmr_out);
940+ // get new dmr from dmr_mag
941+ dmr_up = dmr[0 ]->get_wrapper ();
942+ dmr_down = dmr[1 ]->get_wrapper ();
943+ for (int is = 0 ; is < GlobalV::NSPIN; is++)
944+ {
945+ ModuleBase::GlobalFunc::ZEROS (dmr_up, nnr);
946+ ModuleBase::GlobalFunc::ZEROS (dmr_down, nnr);
947+ }
948+ for (int ir = 0 ; ir < nnr; ir++)
949+ {
950+ dmr_up[ir] = 0.5 * (dmr_mag[ir] + dmr_mag[ir+nnr]);
951+ dmr_down[ir] = 0.5 * (dmr_mag[ir] - dmr_mag[ir+nnr]);
952+ }
953+ // delete
954+ delete[] dmr_mag;
955+ delete[] dmr_mag_save;
956+ }
957+
958+ ModuleBase::timer::tick (" Charge_Mixing" , " mix_dmr" );
959+
960+ return ;
961+ }
962+
740963void Charge_Mixing::mix_reset ()
741964{
742965 this ->mixing ->reset ();
0 commit comments