Skip to content

Commit 0d2d1ae

Browse files
Feature: mixing density and magnetism {mx,my,mz} separately for non-colinear calculation (#3330)
* new mixing for nspin=4 * revert get_drho * change default value and open mixing_beta_mag for nspin=4 * support new mixing of nspin=4 also for PW basis * remove seting nspin in front of seting mixing in Default_2() * update ref of 104_PW_NC_magnetic * update INPUT of 204_NO_KP_NC
1 parent 951811b commit 0d2d1ae

File tree

4 files changed

+107
-35
lines changed

4 files changed

+107
-35
lines changed

source/module_elecstate/module_charge/charge_mixing.cpp

Lines changed: 90 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ void Charge_Mixing::set_mixing(const std::string& mixing_mode_in,
3838
GlobalV::ofs_running<<"mixing_beta: "<< this->mixing_beta <<std::endl;
3939
GlobalV::ofs_running<<"mixing_gg0: "<< this->mixing_gg0 <<std::endl;
4040
GlobalV::ofs_running<<"mixing_gg0_min: "<< GlobalV::MIXING_GG0_MIN <<std::endl;
41-
if (GlobalV::NSPIN==2)
41+
if (GlobalV::NSPIN==2 || GlobalV::NSPIN==4)
4242
{
43-
GlobalV::ofs_running<<"mixing_beta_mag: "<< GlobalV::MIXING_BETA_MAG <<std::endl;
43+
GlobalV::ofs_running<<"mixing_beta_mag: "<< this->mixing_beta_mag <<std::endl;
4444
GlobalV::ofs_running<<"mixing_gg0_mag: "<< GlobalV::MIXING_GG0_MAG <<std::endl;
4545
}
4646
GlobalV::ofs_running<<"mixing_ndim: "<< this->mixing_ndim <<std::endl;
@@ -271,7 +271,6 @@ void Charge_Mixing::mix_rho_recip(Charge* chr)
271271

272272
void Charge_Mixing::mix_rho_recip_new(Charge* chr)
273273
{
274-
// not support nspin=4 yet 2023/11/17
275274
// old support see mix_rho_recip()
276275
if (GlobalV::double_grid)
277276
{
@@ -281,7 +280,7 @@ void Charge_Mixing::mix_rho_recip_new(Charge* chr)
281280
std::complex<double>* rhog_in = nullptr;
282281
std::complex<double>* rhog_out = nullptr;
283282

284-
if (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 4)
283+
if (GlobalV::NSPIN == 1)
285284
{
286285
rhog_in = chr->rhog_save[0];
287286
rhog_out = chr->rhog[0];
@@ -316,8 +315,38 @@ void Charge_Mixing::mix_rho_recip_new(Charge* chr)
316315
};
317316
this->mixing->push_data(this->rho_mdata, rhog_in, rhog_out, screen, twobeta_mix, true);
318317
}
318+
else if (GlobalV::NSPIN == 4)
319+
{
320+
// I do not merge this part with nspin=2 because the method of nspin=2 is almost done,
321+
// while nspin=4 is not finished yet. I will try more methods for nspin=4 in the future.
322+
rhog_in = chr->rhog_save[0];
323+
rhog_out = chr->rhog[0];
324+
const int npw = this->rhopw->npw;
325+
auto screen = std::bind(&Charge_Mixing::Kerker_screen_recip_new, this, std::placeholders::_1); // use old one
326+
auto twobeta_mix
327+
= [this, npw](std::complex<double>* out, const std::complex<double>* in, const std::complex<double>* sres) {
328+
#ifdef _OPENMP
329+
#pragma omp parallel for schedule(static, 256)
330+
#endif
331+
for (int i = 0; i < npw; ++i)
332+
{
333+
out[i] = in[i] + this->mixing_beta * sres[i];
334+
}
335+
// magnetism, mx, my, mz
336+
#ifdef _OPENMP
337+
#pragma omp parallel for schedule(static, 256)
338+
#endif
339+
for (int i = npw; i < 4 * npw; ++i)
340+
{
341+
out[i] = in[i] + this->mixing_beta_mag * sres[i];
342+
}
343+
};
344+
this->mixing->push_data(this->rho_mdata, rhog_in, rhog_out, screen, twobeta_mix, true);
345+
}
319346

320347
// can choose inner_product_recip_new1 or inner_product_recip_new2
348+
// inner_product_recip_new1 is a simple sum
349+
// inner_product_recip_new2 is a hartree-like sum, unit is Ry
321350
auto inner_product_new
322351
= std::bind(&Charge_Mixing::inner_product_recip_new2, this, std::placeholders::_1, std::placeholders::_2);
323352
auto inner_product_old
@@ -326,7 +355,7 @@ void Charge_Mixing::mix_rho_recip_new(Charge* chr)
326355
{
327356
this->mixing->cal_coef(this->rho_mdata, inner_product_new);
328357
}
329-
else if (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 4)
358+
else if (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 4) // nspin=4 can use old inner_product
330359
{
331360
this->mixing->cal_coef(this->rho_mdata, inner_product_old);
332361
}
@@ -344,6 +373,8 @@ void Charge_Mixing::mix_rho_recip_new(Charge* chr)
344373
{
345374
chr->rhopw->recip2real(chr->rhog[is], chr->rho[is]);
346375
}
376+
377+
// renormalize rho in R-space would induce a error in K-space
347378
//chr->renormalize_rho();
348379

349380
// For kinetic energy density
@@ -400,7 +431,7 @@ void Charge_Mixing::mix_rho_real(Charge* chr)
400431
{
401432
double* rhor_in;
402433
double* rhor_out;
403-
if (GlobalV::NSPIN == 1 || GlobalV::NSPIN == 4)
434+
if (GlobalV::NSPIN == 1)
404435
{
405436
rhor_in = chr->rho_save[0];
406437
rhor_out = chr->rho[0];
@@ -420,19 +451,47 @@ void Charge_Mixing::mix_rho_real(Charge* chr)
420451
#ifdef _OPENMP
421452
#pragma omp parallel for schedule(static, 256)
422453
#endif
423-
for (int i = 0; i < nrxx; ++i)
424-
{
425-
out[i] = in[i] + this->mixing_beta * sres[i];
426-
}
454+
for (int i = 0; i < nrxx; ++i)
455+
{
456+
out[i] = in[i] + this->mixing_beta * sres[i];
457+
}
427458
// magnetism
428459
#ifdef _OPENMP
429460
#pragma omp parallel for schedule(static, 256)
430461
#endif
431-
for (int i = nrxx; i < 2 * nrxx; ++i)
432-
{
433-
out[i] = in[i] + this->mixing_beta_mag * sres[i];
434-
}
435-
};
462+
for (int i = nrxx; i < 2 * nrxx; ++i)
463+
{
464+
out[i] = in[i] + this->mixing_beta_mag * sres[i];
465+
}
466+
};
467+
this->mixing->push_data(this->rho_mdata, rhor_in, rhor_out, screen, twobeta_mix, true);
468+
}
469+
else if (GlobalV::NSPIN == 4)
470+
{
471+
// I do not merge this part with nspin=2 because the method of nspin=2 is almost done,
472+
// while nspin=4 is not finished yet. I will try more methods for nspin=4 in the future.
473+
rhor_in = chr->rho_save[0];
474+
rhor_out = chr->rho[0];
475+
const int nrxx = this->rhopw->nrxx;
476+
auto screen = std::bind(&Charge_Mixing::Kerker_screen_real, this, std::placeholders::_1);
477+
auto twobeta_mix
478+
= [this, nrxx](double* out, const double* in, const double* sres) {
479+
#ifdef _OPENMP
480+
#pragma omp parallel for schedule(static, 256)
481+
#endif
482+
for (int i = 0; i < nrxx; ++i)
483+
{
484+
out[i] = in[i] + this->mixing_beta * sres[i];
485+
}
486+
// magnetism, mx, my, mz
487+
#ifdef _OPENMP
488+
#pragma omp parallel for schedule(static, 256)
489+
#endif
490+
for (int i = nrxx; i < 4 * nrxx; ++i)
491+
{
492+
out[i] = in[i] + this->mixing_beta_mag * sres[i];
493+
}
494+
};
436495
this->mixing->push_data(this->rho_mdata, rhor_in, rhor_out, screen, twobeta_mix, true);
437496
}
438497

@@ -642,14 +701,18 @@ void Charge_Mixing::Kerker_screen_recip_new(std::complex<double>* drhog)
642701
for (int is = 0; is < GlobalV::NSPIN; ++is)
643702
{
644703
// new mixing method only support nspin=2 not nspin=4
645-
if (is == 1 && GlobalV::NSPIN == 2)
704+
if (is >= 1)
646705
{
647706
if (GlobalV::MIXING_GG0_MAG <= 0.0001 || GlobalV::MIXING_BETA_MAG <= 0.1)
648707
{
649-
for (int ig = 0; ig < this->rhopw->npw; ig++)
650-
{
651-
drhog[is * this->rhopw->npw + ig] *= 1;
652-
}
708+
#ifdef __DEBUG
709+
assert(is == 1); // make sure break works
710+
#endif
711+
double is_mag = GlobalV::NSPIN - 1;
712+
//for (int ig = 0; ig < this->rhopw->npw * is_mag; ig++)
713+
//{
714+
// drhog[is * this->rhopw->npw + ig] *= 1;
715+
//}
653716
break;
654717
}
655718
fac = GlobalV::MIXING_GG0_MAG;
@@ -692,13 +755,17 @@ void Charge_Mixing::Kerker_screen_real(double* drhor)
692755
for (int is = 0; is < GlobalV::NSPIN; is++)
693756
{
694757

695-
if (is == 1 && GlobalV::NSPIN == 2)
758+
if (is >= 1)
696759
{
697760
if (GlobalV::MIXING_GG0_MAG <= 0.0001 || GlobalV::MIXING_BETA_MAG <= 0.1)
698761
{
699-
for (int ig = 0; ig < this->rhopw->npw; ig++)
762+
#ifdef __DEBUG
763+
assert(is == 1); // make sure break works
764+
#endif
765+
double is_mag = GlobalV::NSPIN - 1;
766+
for (int ig = 0; ig < this->rhopw->npw * is_mag; ig++)
700767
{
701-
drhog[is * this->rhopw->npw + ig] *= 0;
768+
drhog[is * this->rhopw->npw + ig] = 0;
702769
}
703770
break;
704771
}

source/module_io/input.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ void Input::Default(void)
301301
mixing_beta = -10;
302302
mixing_ndim = 8;
303303
mixing_gg0 = 1.00; // use Kerker defaultly
304-
mixing_beta_mag = -10.0; // only set when nspin == 2
304+
mixing_beta_mag = -10.0; // only set when nspin == 2 || nspin == 4
305305
mixing_gg0_mag = 0.0; // defaultly exclude Kerker from mixing magnetic density
306306
mixing_gg0_min = 0.1; // defaultly minimum kerker coefficient
307307
mixing_tau = false;
@@ -2975,6 +2975,13 @@ void Input::Default_2(void) // jiyy add 2019-08-04
29752975
scf_thr_type = 1;
29762976
}
29772977
}
2978+
2979+
// set nspin with noncolin
2980+
if (noncolin || lspinorb)
2981+
{
2982+
nspin = 4;
2983+
}
2984+
29782985
// mixing parameters
29792986
if (mixing_beta < 0.0)
29802987
{
@@ -2990,28 +2997,25 @@ void Input::Default_2(void) // jiyy add 2019-08-04
29902997
}
29912998
else if (nspin == 4) // I will add this
29922999
{
2993-
mixing_beta = 0.2;
3000+
mixing_beta = 0.4;
3001+
mixing_beta_mag = 1.6;
3002+
mixing_gg0_mag = 0.0;
29943003
}
29953004
}
29963005
else
29973006
{
2998-
if (nspin == 2 && mixing_beta_mag < 0.0)
3007+
if ((nspin == 2 || nspin == 4) && mixing_beta_mag < 0.0)
29993008
{
30003009
if (mixing_beta <= 0.4)
30013010
{
30023011
mixing_beta_mag = 4 * mixing_beta;
30033012
}
30043013
else
30053014
{
3006-
mixing_beta_mag = 1.6;
3015+
mixing_beta_mag = 1.6; // 1.6 can be discussed
30073016
}
30083017
}
30093018
}
3010-
// set nspin with noncolin
3011-
if (noncolin || lspinorb)
3012-
{
3013-
nspin = 4;
3014-
}
30153019
}
30163020
#ifdef __MPI
30173021
void Input::Bcast()
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
etotref -5866.174730432665
2-
etotperatomref -2933.0873652163
1+
etotref -5866.197307043378
2+
etotperatomref -2933.0986535217
33
pointgroupref O_h
44
spacegroupref O_h
55
nksibzref 1
6-
totaltimeref 0.77367
6+
totaltimeref 2.23

tests/integrate/204_NO_KP_NC_deltaspin/INPUT

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ smearing_sigma 0.07
2525

2626
mixing_type pulay
2727
mixing_beta 0.3
28+
mixing_beta_mag 0.3
2829
mixing_gg0 0.0
2930

3031
ks_solver genelpa

0 commit comments

Comments
 (0)