Skip to content

Commit c9e4514

Browse files
author
dyzheng
committed
Fix: lack of switch_dmr
1 parent d30a434 commit c9e4514

File tree

4 files changed

+94
-8
lines changed

4 files changed

+94
-8
lines changed

source/module_elecstate/module_dm/density_matrix.cpp

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ DensityMatrix<TK, TR>::~DensityMatrix()
2222
{
2323
delete it;
2424
}
25+
delete[] this->dmr_tmp_;
2526
}
2627

2728
template <typename TK, typename TR>
@@ -627,12 +628,12 @@ void DensityMatrix<std::complex<double>, double>::cal_DMR_full(hamilt::HContaine
627628
#endif
628629
// loop over k-points
629630
// calculate full matrix for complex density matrix
630-
for (int ik = 0; ik < this->_nks; ++ik)
631+
for (int ik = 0; ik < this->_nk; ++ik)
631632
{
632633
// cal k_phase
633634
// if TK==std::complex<double>, kphase is e^{ikR}
634635
const ModuleBase::Vector3<double> dR(r_index[0], r_index[1], r_index[2]);
635-
const double arg = (this->_kv->kvec_d[ik] * dR) * ModuleBase::TWO_PI;
636+
const double arg = (this->_kvec_d[ik] * dR) * ModuleBase::TWO_PI;
636637
double sinp, cosp;
637638
ModuleBase::libm::sincos(arg, &sinp, &cosp);
638639
std::complex<double> kphase = std::complex<double>(cosp, sinp);
@@ -983,6 +984,82 @@ void DensityMatrix<std::complex<double>, double>::write_DMK(const std::string di
983984
ofs.close();
984985
}
985986

987+
// switch_dmr
988+
template <typename TK, typename TR>
989+
void DensityMatrix<TK, TR>::switch_dmr(const int mode)
990+
{
991+
ModuleBase::TITLE("DensityMatrix", "switch_dmr");
992+
if (this->_nspin != 2)
993+
{
994+
return;
995+
}
996+
else
997+
{
998+
ModuleBase::timer::tick("DensityMatrix", "switch_dmr");
999+
switch(mode)
1000+
{
1001+
case 0:
1002+
// switch to original density matrix
1003+
if (this->dmr_tmp_ != nullptr && this->dmr_origin_.size() != 0)
1004+
{
1005+
this->_DMR[0]->allocate(this->dmr_origin_.data(), false);
1006+
delete[] this->dmr_tmp_;
1007+
this->dmr_tmp_ = nullptr;
1008+
}
1009+
// else: do nothing
1010+
break;
1011+
case 1:
1012+
// switch to total magnetization density matrix, dmr_up + dmr_down
1013+
if(this->dmr_tmp_ == nullptr)
1014+
{
1015+
const size_t size = this->_DMR[0]->get_nnr();
1016+
this->dmr_tmp_ = new TR[size];
1017+
this->dmr_origin_.resize(size);
1018+
for (int i = 0; i < size; ++i)
1019+
{
1020+
this->dmr_tmp_[i] = this->dmr_origin_[i] + this->_DMR[1]->get_wrapper()[i];
1021+
}
1022+
this->_DMR[0]->allocate(this->dmr_tmp_, false);
1023+
}
1024+
else
1025+
{
1026+
const size_t size = this->_DMR[0]->get_nnr();
1027+
for (int i = 0; i < size; ++i)
1028+
{
1029+
this->dmr_tmp_[i] = this->dmr_origin_[i] - this->_DMR[1]->get_wrapper()[i];
1030+
}
1031+
}
1032+
break;
1033+
case 2:
1034+
// switch to magnetization density matrix, dmr_up - dmr_down
1035+
if(this->dmr_tmp_ == nullptr)
1036+
{
1037+
const size_t size = this->_DMR[0]->get_nnr();
1038+
this->dmr_tmp_ = new TR[size];
1039+
this->dmr_origin_.resize(size);
1040+
for (int i = 0; i < size; ++i)
1041+
{
1042+
this->dmr_origin_[i] = this->_DMR[0]->get_wrapper()[i];
1043+
this->dmr_tmp_[i] = this->dmr_origin_[i] - this->_DMR[1]->get_wrapper()[i];
1044+
}
1045+
this->_DMR[0]->allocate(this->dmr_tmp_, false);
1046+
}
1047+
else
1048+
{
1049+
const size_t size = this->_DMR[0]->get_nnr();
1050+
for (int i = 0; i < size; ++i)
1051+
{
1052+
this->dmr_tmp_[i] = this->dmr_origin_[i] - this->_DMR[1]->get_wrapper()[i];
1053+
}
1054+
}
1055+
break;
1056+
default:
1057+
throw std::string("Unknown mode in switch_dmr");
1058+
}
1059+
ModuleBase::timer::tick("DensityMatrix", "switch_dmr");
1060+
}
1061+
}
1062+
9861063
// T of HContainer can be double or complex<double>
9871064
template class DensityMatrix<double, double>; // Gamma-Only case
9881065
template class DensityMatrix<std::complex<double>, double>; // Multi-k case

source/module_elecstate/module_dm/density_matrix.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,12 @@ class DensityMatrix
196196
*/
197197
void sum_DMR_spin();
198198

199+
/**
200+
* @brief (Only nspin=2) switch DMR to total density matrix or magnetization density matrix
201+
* @param mode 0 - original density matrix; 1 - total density matrix; 2 - magnetization density matrix
202+
*/
203+
void switch_dmr(const int mode);
204+
199205
/**
200206
* @brief write density matrix dm(ik) into *.dmk
201207
* @param directory directory of *.dmk files
@@ -275,6 +281,9 @@ class DensityMatrix
275281
*/
276282
int _nk = 0;
277283

284+
/// temporary pointers for switch DMR, only used with nspin=2
285+
std::vector<TR> dmr_origin_;
286+
TR* dmr_tmp_ = nullptr;
278287

279288
};
280289

source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,25 +171,26 @@ void Force_Stress_LCAO<T>::getForceStress(const bool isforce,
171171
pv,
172172
kv);
173173
// calculate force and stress for Nonlocal part
174-
if(GlobalV::NSPIN!=4)
174+
if(PARAM.inp.nspin != 4)
175175
{
176176
hamilt::NonlocalNew<hamilt::OperatorLCAO<T, double>> tmp_nonlocal(
177177
nullptr,
178178
kv.kvec_d,
179179
nullptr,
180180
&GlobalC::ucell,
181+
orb.cutoffs(),
181182
&GlobalC::GridD,
182183
two_center_bundle.overlap_orb_beta.get()
183184
);
184185

185186
const auto* dm_p = dynamic_cast<const elecstate::ElecStateLCAO<T>*>(pelec)->get_DM();
186-
if(GlobalV::NSPIN==2)
187+
if(PARAM.inp.nspin == 2)
187188
{
188189
const_cast<elecstate::DensityMatrix<T, double>*>(dm_p)->switch_dmr(1);
189190
}
190191
const hamilt::HContainer<double>* dmr = dm_p->get_DMR_pointer(1);
191192
tmp_nonlocal.cal_force_stress(isforce, isstress, dmr, fvnl_dbeta, svnl_dbeta);
192-
if(GlobalV::NSPIN==2)
193+
if(PARAM.inp.nspin == 2)
193194
{
194195
const_cast<elecstate::DensityMatrix<T, double>*>(dm_p)->switch_dmr(0);
195196
}
@@ -201,6 +202,7 @@ void Force_Stress_LCAO<T>::getForceStress(const bool isforce,
201202
kv.kvec_d,
202203
nullptr,
203204
&GlobalC::ucell,
205+
orb.cutoffs(),
204206
&GlobalC::GridD,
205207
two_center_bundle.overlap_orb_beta.get()
206208
);

source/module_hamilt_lcao/hamilt_lcaodft/operator_lcao/nonlocal_force_stress.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,11 @@ void NonlocalNew<OperatorLCAO<TK, TR>>::cal_force_stress(const bool cal_force,
4747
const int iat1 = ucell->itia2iat(T1, I1);
4848
const ModuleBase::Vector3<int>& R_index1 = adjs.box[ad];
4949
// choose the real adjacent atoms
50-
const LCAO_Orbitals& orb = LCAO_Orbitals::get_const_instance();
5150
// Note: the distance of atoms should less than the cutoff radius,
5251
// When equal, the theoretical value of matrix element is zero,
5352
// but the calculated value is not zero due to the numerical error, which would lead to result changes.
5453
if (this->ucell->cal_dtau(iat0, iat1, R_index1).norm() * this->ucell->lat0
55-
< orb.Phi[T1].getRcut() + this->ucell->infoNL.Beta[this->current_type].get_rcut_max())
54+
< orb_cutoff_[T1] + this->ucell->infoNL.Beta[this->current_type].get_rcut_max())
5655
{
5756
is_adj[ad] = true;
5857
}
@@ -68,7 +67,6 @@ void NonlocalNew<OperatorLCAO<TK, TR>>::cal_force_stress(const bool cal_force,
6867
const ModuleBase::Vector3<double>& tau1 = adjs.adjacent_tau[ad];
6968
const Atom* atom1 = &ucell->atoms[T1];
7069

71-
const LCAO_Orbitals& orb = LCAO_Orbitals::get_const_instance();
7270
auto all_indexes = paraV->get_indexes_row(iat1);
7371
auto col_indexes = paraV->get_indexes_col(iat1);
7472
// insert col_indexes into all_indexes to get universal set with no repeat elements

0 commit comments

Comments
 (0)