Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 38 additions & 13 deletions source/module_elecstate/module_charge/charge_mixing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ void Charge_Mixing::set_mixing(const std::string& mixing_mode_in,
ModuleBase::WARNING_QUIT("Charge_Mixing", "You'd better set mixing_beta_mag >= 0.0!");
}

if (!(this->mixing_mode == "plain" || this->mixing_mode == "broyden" || this->mixing_mode == "pulay"))
{
ModuleBase::WARNING_QUIT("Charge_Mixing", "This Mixing mode is not implemended yet,coming soon.");
}

// print into running.log
GlobalV::ofs_running<<"\n----------- Double Check Mixing Parameters Begin ------------"<<std::endl;
GlobalV::ofs_running<<"mixing_type: "<< this->mixing_mode <<std::endl;
Expand All @@ -70,6 +75,17 @@ void Charge_Mixing::set_mixing(const std::string& mixing_mode_in,
GlobalV::ofs_running<<"mixing_ndim: "<< this->mixing_ndim <<std::endl;
GlobalV::ofs_running<<"----------- Double Check Mixing Parameters End ------------"<<std::endl;

return;
}

void Charge_Mixing::init_mixing()
{
// this init should be called at the 1-st iteration of each scf loop

ModuleBase::TITLE("Charge_Mixing", "init_mixing");
ModuleBase::timer::tick("Charge_Mixing", "init_mixing");

// (re)construct mixing object
if (this->mixing_mode == "broyden")
{
delete this->mixing;
Expand All @@ -89,6 +105,7 @@ void Charge_Mixing::set_mixing(const std::string& mixing_mode_in,
{
ModuleBase::WARNING_QUIT("Charge_Mixing", "This Mixing mode is not implemended yet,coming soon.");
}

if (GlobalV::double_grid)
{
// ONLY smooth part of charge density is mixed by specific mixing method
Expand All @@ -97,6 +114,8 @@ void Charge_Mixing::set_mixing(const std::string& mixing_mode_in,
this->mixing_highf = new Base_Mixing::Plain_Mixing(this->mixing_beta);
}

// allocate memory for mixing data, if exists, free it first and then allocate new memory
// initailize rho_mdata
if (GlobalV::SCF_THR_TYPE == 1)
{
if (GlobalV::NSPIN == 4 && GlobalV::MIXING_ANGLE > 0 )
Expand All @@ -123,14 +142,29 @@ void Charge_Mixing::set_mixing(const std::string& mixing_mode_in,
this->mixing->init_mixing_data(this->rho_mdata, this->rhopw->nrxx * GlobalV::NSPIN, sizeof(double));
}
}

// initailize tau_mdata
if ((XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) && mixing_tau)
{
if (GlobalV::SCF_THR_TYPE == 1)
{
this->mixing->init_mixing_data(this->tau_mdata,
this->rhopw->npw * GlobalV::NSPIN,
sizeof(std::complex<double>));
}
else
{
this->mixing->init_mixing_data(this->tau_mdata, this->rhopw->nrxx * GlobalV::NSPIN, sizeof(double));
}
}

// initailize nhat_mdata
#ifdef USE_PAW
if(GlobalV::use_paw) this->mixing->init_mixing_data(this->nhat_mdata, this->rhopw->nrxx * GlobalV::NSPIN, sizeof(double));
#endif

// Note: we can not init tau_mdata here temporarily, since set_xc_type() is after it.
// you can find initalize tau_mdata in mix_reset();
// this->mixing->init_mixing_data(this->tau_mdata, this->rhopw->nrxx * GlobalV::NSPIN, sizeof(double));
ModuleBase::timer::tick("Charge_Mixing", "init_mixing");

return;
}

Expand Down Expand Up @@ -933,16 +967,7 @@ void Charge_Mixing::mix_reset()
// initailize tau_mdata
if ((XC_Functional::get_func_type() == 3 || XC_Functional::get_func_type() == 5) && mixing_tau)
{
if (GlobalV::SCF_THR_TYPE == 1)
{
this->mixing->init_mixing_data(this->tau_mdata,
this->rhopw->npw * GlobalV::NSPIN,
sizeof(std::complex<double>));
}
else
{
this->mixing->init_mixing_data(this->tau_mdata, this->rhopw->nrxx * GlobalV::NSPIN, sizeof(double));
}
this->tau_mdata.reset();
}
// reset for paw
#ifdef USE_PAW
Expand Down
42 changes: 24 additions & 18 deletions source/module_elecstate/module_charge/charge_mixing.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,6 @@ class Charge_Mixing
Charge_Mixing();
~Charge_Mixing();

/**
* @brief reset mixing
*/
void mix_reset();

/**
* @brief charge mixing
* @param chr pointer of Charge object
*/
void mix_rho(Charge* chr);

/**
* @brief density matrix mixing, only for LCAO
* @param DM pointer of DensityMatrix object
*/
void mix_dmr(elecstate::DensityMatrix<double, double>* DM);
void mix_dmr(elecstate::DensityMatrix<std::complex<double>, double>* DM);

/**
* @brief Set all private mixing paramters
* @param mixing_mode_in mixing mode: "plain", "broyden", "pulay"
Expand All @@ -66,17 +48,41 @@ class Charge_Mixing
const double& mixing_angle_in,
const bool& mixing_dmr_in);

/**
* @brief initialize mixing, including constructing mixing and allocating memory for mixing data
* @brief this function should be called at eachiterinit()
*/
void init_mixing();

/**
* @brief allocate memory of dmr_mdata
* @param nnr size of real-space density matrix
*/
void allocate_mixing_dmr(int nnr);

/**
* @brief charge mixing
* @param chr pointer of Charge object
*/
void mix_rho(Charge* chr);

/**
* @brief density matrix mixing, only for LCAO
* @param DM pointer of DensityMatrix object
*/
void mix_dmr(elecstate::DensityMatrix<double, double>* DM);
void mix_dmr(elecstate::DensityMatrix<std::complex<double>, double>* DM);

/**
* @brief Get the drho
*
*/
double get_drho(Charge* chr, const double nelec);

/**
* @brief reset mixing, actually we only call init_mixing() to reset mixing instead of this function
*/
void mix_reset();

/**
* @brief Set the smooth and dense grids
Expand Down
107 changes: 67 additions & 40 deletions source/module_elecstate/test/charge_mixing_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,13 @@ UnitCell ucell;
* - Tested Functions:
* - SetMixingTest:
* Charge_Mixing::set_mixing(mixing_mode_in,mixing_beta_in,mixing_ndim_in,mixing_gg0_in,mixing_tau_in)
* Charge_Mixing::init_mixing()
* Charge_Mixing::set_rhopw(rhopw_in)
* Charge_Mixing::get_mixing_mode()
* Charge_Mixing::get_mixing_beta()
* Charge_Mixing::get_mixing_ndim()
* Charge_Mixing::get_mixing_gg0()
* - set the basic parameters of class charge_mixing
* - AutoSetTest: Charge_Mixing::auto_set(bandgap_in, ucell_)
* Charge_Mixing::need_auto_set()
* - auto-set the parameters of class charge_mixing
* - KerkerScreenTest: Charge_Mixing::Kerker_screen_recip(drhog)
* Charge_Mixing::Kerker_screen_real(drhog)
* - screen drho with Kerker method
Expand Down Expand Up @@ -120,8 +118,6 @@ TEST_F(ChargeMixingTest, SetMixingTest)
GlobalV::MIXING_NDIM = 1;
GlobalV::MIXING_GG0 = 1.0;

FUNC_TYPE = 1;
GlobalV::SCF_THR_TYPE = 1;
CMtest.set_mixing(GlobalV::MIXING_MODE,
GlobalV::MIXING_BETA,
GlobalV::MIXING_NDIM,
Expand All @@ -132,7 +128,6 @@ TEST_F(ChargeMixingTest, SetMixingTest)
GlobalV::MIXING_GG0_MIN,
GlobalV::MIXING_ANGLE,
GlobalV::MIXING_DMR);
EXPECT_EQ(CMtest.rho_mdata.length, pw_basis.npw);
EXPECT_EQ(CMtest.get_mixing_mode(), "broyden");
EXPECT_EQ(CMtest.get_mixing_beta(), 1.0);
EXPECT_EQ(CMtest.get_mixing_ndim(), 1);
Expand All @@ -144,23 +139,8 @@ TEST_F(ChargeMixingTest, SetMixingTest)
EXPECT_EQ(CMtest.mixing_angle, -10.0);
EXPECT_EQ(CMtest.mixing_dmr, false);

GlobalV::SCF_THR_TYPE = 2;
CMtest.set_mixing(GlobalV::MIXING_MODE,
GlobalV::MIXING_BETA,
GlobalV::MIXING_NDIM,
GlobalV::MIXING_GG0,
GlobalV::MIXING_TAU,
GlobalV::MIXING_BETA_MAG,
GlobalV::MIXING_GG0_MAG,
GlobalV::MIXING_GG0_MIN,
GlobalV::MIXING_ANGLE,
GlobalV::MIXING_DMR);
EXPECT_EQ(CMtest.rho_mdata.length, pw_basis.nrxx);

FUNC_TYPE = 3;
GlobalV::MIXING_TAU = true;
GlobalV::MIXING_MODE = "plain";
GlobalV::SCF_THR_TYPE = 1;
CMtest.set_mixing(GlobalV::MIXING_MODE,
GlobalV::MIXING_BETA,
GlobalV::MIXING_NDIM,
Expand All @@ -171,25 +151,9 @@ TEST_F(ChargeMixingTest, SetMixingTest)
GlobalV::MIXING_GG0_MIN,
GlobalV::MIXING_ANGLE,
GlobalV::MIXING_DMR);
CMtest.mix_reset();
EXPECT_EQ(CMtest.tau_mdata.length, pw_basis.npw);
EXPECT_EQ(CMtest.mixing_mode, "plain");
EXPECT_EQ(CMtest.mixing_tau, true);

GlobalV::SCF_THR_TYPE = 2;
CMtest.set_mixing(GlobalV::MIXING_MODE,
GlobalV::MIXING_BETA,
GlobalV::MIXING_NDIM,
GlobalV::MIXING_GG0,
GlobalV::MIXING_TAU,
GlobalV::MIXING_BETA_MAG,
GlobalV::MIXING_GG0_MAG,
GlobalV::MIXING_GG0_MIN,
GlobalV::MIXING_ANGLE,
GlobalV::MIXING_DMR);
CMtest.mix_reset();
EXPECT_EQ(CMtest.tau_mdata.length, pw_basis.nrxx);

GlobalV::MIXING_BETA = 1.1;
std::string output;
testing::internal::CaptureStdout();
Expand Down Expand Up @@ -242,6 +206,69 @@ TEST_F(ChargeMixingTest, SetMixingTest)
EXPECT_THAT(output, testing::HasSubstr("This Mixing mode is not implemended yet,coming soon."));
}

TEST_F(ChargeMixingTest, InitMixingTest)
{
omp_set_num_threads(1);
GlobalV::NSPIN = 1;
FUNC_TYPE = 1;
Charge_Mixing CMtest;
CMtest.set_rhopw(&pw_basis, &pw_basis);

CMtest.set_mixing(GlobalV::MIXING_MODE,
GlobalV::MIXING_BETA,
GlobalV::MIXING_NDIM,
GlobalV::MIXING_GG0,
GlobalV::MIXING_TAU,
GlobalV::MIXING_BETA_MAG,
GlobalV::MIXING_GG0_MAG,
GlobalV::MIXING_GG0_MIN,
GlobalV::MIXING_ANGLE,
GlobalV::MIXING_DMR);

GlobalV::SCF_THR_TYPE = 1;
CMtest.init_mixing();
EXPECT_EQ(CMtest.rho_mdata.length, pw_basis.npw);

GlobalV::SCF_THR_TYPE = 2;
CMtest.init_mixing();
EXPECT_EQ(CMtest.rho_mdata.length, pw_basis.nrxx);

GlobalV::NSPIN = 4;
CMtest.init_mixing();
EXPECT_EQ(CMtest.rho_mdata.length, 4 * pw_basis.nrxx);

GlobalV::NSPIN = 1;
GlobalV::MIXING_TAU = true;
CMtest.set_mixing(GlobalV::MIXING_MODE,
GlobalV::MIXING_BETA,
GlobalV::MIXING_NDIM,
GlobalV::MIXING_GG0,
GlobalV::MIXING_TAU,
GlobalV::MIXING_BETA_MAG,
GlobalV::MIXING_GG0_MAG,
GlobalV::MIXING_GG0_MIN,
GlobalV::MIXING_ANGLE,
GlobalV::MIXING_DMR);
FUNC_TYPE = 3;
CMtest.init_mixing();
EXPECT_EQ(CMtest.tau_mdata.length, pw_basis.nrxx);

GlobalV::NSPIN = 4;
GlobalV::MIXING_ANGLE = 1.0;
CMtest.set_mixing(GlobalV::MIXING_MODE,
GlobalV::MIXING_BETA,
GlobalV::MIXING_NDIM,
GlobalV::MIXING_GG0,
GlobalV::MIXING_TAU,
GlobalV::MIXING_BETA_MAG,
GlobalV::MIXING_GG0_MAG,
GlobalV::MIXING_GG0_MIN,
GlobalV::MIXING_ANGLE,
GlobalV::MIXING_DMR);
CMtest.init_mixing();
EXPECT_EQ(CMtest.rho_mdata.length, 2 * pw_basis.nrxx);
}

TEST_F(ChargeMixingTest, KerkerScreenRecipTest)
{
Charge_Mixing CMtest;
Expand Down Expand Up @@ -535,7 +562,7 @@ TEST_F(ChargeMixingTest, MixRhoTest)
GlobalV::MIXING_GG0_MIN,
GlobalV::MIXING_ANGLE,
GlobalV::MIXING_DMR);
CMtest_recip.mix_reset();
CMtest_recip.init_mixing();
for(int i = 0 ; i < nspin * npw; ++i)
{
charge._space_rhog[i] = recip_ref[i];
Expand Down Expand Up @@ -574,7 +601,7 @@ TEST_F(ChargeMixingTest, MixRhoTest)
GlobalV::MIXING_GG0_MIN,
GlobalV::MIXING_ANGLE,
GlobalV::MIXING_DMR);
CMtest_real.mix_reset();
CMtest_real.init_mixing();
for(int i = 0 ; i < nspin * nrxx; ++i)
{
charge._space_rho[i] = real_ref[i];
Expand Down Expand Up @@ -669,7 +696,7 @@ TEST_F(ChargeMixingTest, MixDoubleGridRhoTest)
GlobalV::MIXING_GG0_MIN,
GlobalV::MIXING_ANGLE,
GlobalV::MIXING_DMR);
CMtest_recip.mix_reset();
CMtest_recip.init_mixing();
for (int i = 0; i < nspin * npw; ++i)
{
charge._space_rhog[i] = recip_ref[i];
Expand Down
Loading