Skip to content

Commit f7dbc92

Browse files
author
dyzheng
committed
Refactor&Fix: soc force&stress for LCAO
1 parent 3984296 commit f7dbc92

File tree

8 files changed

+628
-24
lines changed

8 files changed

+628
-24
lines changed

source/module_elecstate/module_dm/density_matrix.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,82 @@ void DensityMatrix<std::complex<double>, double>::cal_DMR()
589589
ModuleBase::timer::tick("DensityMatrix", "cal_DMR");
590590
}
591591

592+
// calculate DMR from DMK using blas for multi-k calculation
593+
template <>
594+
void DensityMatrix<double, double>::cal_DMR_full(hamilt::HContainer<std::complex<double>>* dmR_out)const{}
595+
template <>
596+
void DensityMatrix<std::complex<double>, double>::cal_DMR_full(hamilt::HContainer<std::complex<double>>* dmR_out)const
597+
{
598+
ModuleBase::TITLE("DensityMatrix", "cal_DMR_full");
599+
600+
ModuleBase::timer::tick("DensityMatrix", "cal_DMR_full");
601+
int ld_hk = this->_paraV->nrow;
602+
int ld_hk2 = 2 * ld_hk;
603+
hamilt::HContainer<std::complex<double>>* tmp_DMR = dmR_out;
604+
// set zero since this function is called in every scf step
605+
tmp_DMR->set_zero();
606+
#ifdef _OPENMP
607+
#pragma omp parallel for
608+
#endif
609+
for (int i = 0; i < tmp_DMR->size_atom_pairs(); ++i)
610+
{
611+
auto& tmp_ap = tmp_DMR->get_atom_pair(i);
612+
int iat1 = tmp_ap.get_atom_i();
613+
int iat2 = tmp_ap.get_atom_j();
614+
// get global indexes of whole matrix for each atom in this process
615+
int row_ap = this->_paraV->atom_begin_row[iat1];
616+
int col_ap = this->_paraV->atom_begin_col[iat2];
617+
if (row_ap == -1 || col_ap == -1)
618+
{
619+
throw std::string("Atom-pair not belong this process");
620+
}
621+
for (int ir = 0; ir < tmp_ap.get_R_size(); ++ir)
622+
{
623+
const ModuleBase::Vector3<int> r_index = tmp_ap.get_R_index(ir);
624+
auto* tmp_matrix = tmp_ap.find_matrix(r_index);
625+
#ifdef __DEBUG
626+
if (tmp_matrix == nullptr)
627+
{
628+
std::cout << "tmp_matrix is nullptr" << std::endl;
629+
continue;
630+
}
631+
#endif
632+
// loop over k-points
633+
// calculate full matrix for complex density matrix
634+
for (int ik = 0; ik < this->_nks; ++ik)
635+
{
636+
// cal k_phase
637+
// if TK==std::complex<double>, kphase is e^{ikR}
638+
const ModuleBase::Vector3<double> dR(r_index[0], r_index[1], r_index[2]);
639+
const double arg = (this->_kv->kvec_d[ik] * dR) * ModuleBase::TWO_PI;
640+
double sinp, cosp;
641+
ModuleBase::libm::sincos(arg, &sinp, &cosp);
642+
std::complex<double> kphase = std::complex<double>(cosp, sinp);
643+
// set DMR element
644+
std::complex<double>* tmp_DMR_pointer = tmp_matrix->get_pointer();
645+
const std::complex<double>* tmp_DMK_pointer = this->_DMK[ik].data();
646+
double* DMK_real_pointer = nullptr;
647+
double* DMK_imag_pointer = nullptr;
648+
// jump DMK to fill DMR
649+
// DMR is row-major, DMK is column-major
650+
tmp_DMK_pointer += col_ap * this->_paraV->nrow + row_ap;
651+
for (int mu = 0; mu < this->_paraV->get_row_size(iat1); ++mu)
652+
{
653+
BlasConnector::axpy(this->_paraV->get_col_size(iat2),
654+
kphase,
655+
tmp_DMK_pointer,
656+
ld_hk,
657+
tmp_DMR_pointer,
658+
1);
659+
tmp_DMK_pointer += 1;
660+
tmp_DMR_pointer += this->_paraV->get_col_size(iat2);
661+
}
662+
}
663+
}
664+
}
665+
ModuleBase::timer::tick("DensityMatrix", "cal_DMR_full");
666+
}
667+
592668
// calculate DMR from DMK using blas for multi-k calculation, without summing over k-points
593669
template <>
594670
void DensityMatrix<std::complex<double>, double>::cal_DMR(const int ik)

source/module_elecstate/module_dm/density_matrix.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ class DensityMatrix
179179
*/
180180
void cal_DMR();
181181

182+
void cal_DMR_full(hamilt::HContainer<std::complex<double>>* dmR_out) const;
183+
182184
/**
183185
* @brief calculate density matrix DMR from dm(k) using blas::axpy for multi-k calculation, without summing over k-points
184186
*/

source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "module_hamilt_lcao/module_deepks/LCAO_deepks_io.h" // mohan add 2024-07-22
1919
#endif
2020
#include "module_hamilt_lcao/hamilt_lcaodft/operator_lcao/dftu_lcao.h"
21+
#include "module_hamilt_lcao/hamilt_lcaodft/operator_lcao/nonlocal_new.h"
22+
#include "module_elecstate/elecstate_lcao.h"
2123

2224
template <typename T>
2325
Force_Stress_LCAO<T>::Force_Stress_LCAO(Record_adj& ra, const int nat_in) : RA(&ra), f_pw(nat_in), nat(nat_in)
@@ -168,6 +170,50 @@ void Force_Stress_LCAO<T>::getForceStress(const bool isforce,
168170
orb,
169171
pv,
170172
kv);
173+
// calculate force and stress for Nonlocal part
174+
if(GlobalV::NSPIN!=4)
175+
{
176+
hamilt::NonlocalNew<hamilt::OperatorLCAO<T, double>> tmp_nonlocal(
177+
nullptr,
178+
kv.kvec_d,
179+
nullptr,
180+
&GlobalC::ucell,
181+
&GlobalC::GridD,
182+
two_center_bundle.overlap_orb_beta.get()
183+
);
184+
185+
const auto* dm_p = dynamic_cast<const elecstate::ElecStateLCAO<T>*>(pelec)->get_DM();
186+
if(GlobalV::NSPIN==2)
187+
{
188+
const_cast<elecstate::DensityMatrix<T, double>*>(dm_p)->switch_dmr(2);
189+
}
190+
const hamilt::HContainer<double>* dmr = dm_p->get_DMR_pointer(1);
191+
tmp_nonlocal.cal_force_stress(isforce, isstress, dmr, fvnl_dbeta, svnl_dbeta);
192+
if(GlobalV::NSPIN==2)
193+
{
194+
const_cast<elecstate::DensityMatrix<T, double>*>(dm_p)->switch_dmr(0);
195+
}
196+
}
197+
else
198+
{
199+
hamilt::NonlocalNew<hamilt::OperatorLCAO<std::complex<double>, std::complex<double>>> tmp_nonlocal(
200+
nullptr,
201+
kv.kvec_d,
202+
nullptr,
203+
&GlobalC::ucell,
204+
&GlobalC::GridD,
205+
two_center_bundle.overlap_orb_beta.get()
206+
);
207+
208+
const auto* dm_p = dynamic_cast<const elecstate::ElecStateLCAO<std::complex<double>>*>(pelec)->get_DM();
209+
hamilt::HContainer<std::complex<double>> tmp_dmr(dm_p->get_DMR_pointer(1)->get_paraV());
210+
std::vector<int> ijrs = dm_p->get_DMR_pointer(1)->get_ijr_info();
211+
tmp_dmr.insert_ijrs(&ijrs);
212+
tmp_dmr.allocate();
213+
dm_p->cal_DMR_full(&tmp_dmr);
214+
tmp_nonlocal.cal_force_stress(isforce, isstress, &tmp_dmr, fvnl_dbeta, svnl_dbeta);
215+
}
216+
171217

172218
//! forces and stress from vdw
173219
// Peize Lin add 2014-04-04, update 2021-03-09

source/module_hamilt_lcao/hamilt_lcaodft/FORCE_gamma.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,6 @@ void Force_LCAO<double>::allocate(const Parallel_Orbitals& pv,
106106
&GlobalC::GridD,
107107
nullptr);
108108

109-
LCAO_domain::build_Nonlocal_mu_new(pv,
110-
fsr,
111-
nullptr,
112-
cal_deri,
113-
GlobalC::ucell,
114-
orb,
115-
*(two_center_bundle.overlap_orb_beta),
116-
&GlobalC::GridD);
117-
118109
// calculate asynchronous S matrix to output for Hefei-NAMD
119110
if (PARAM.inp.cal_syns)
120111
{
@@ -228,7 +219,7 @@ void Force_LCAO<double>::ftable(const bool isforce,
228219
//tvnl_dphi
229220
PulayForceStress::cal_pulay_fs(ftvnl_dphi, stvnl_dphi, *dm, ucell, pv, dHx, dHxy, isforce, isstress);
230221

231-
this->cal_fvnl_dbeta(dm,
222+
/*this->cal_fvnl_dbeta(dm,
232223
pv,
233224
ucell,
234225
orb,
@@ -237,7 +228,7 @@ void Force_LCAO<double>::ftable(const bool isforce,
237228
isforce,
238229
isstress,
239230
fvnl_dbeta,
240-
svnl_dbeta);
231+
svnl_dbeta);*/
241232

242233
// vl_dphi
243234
PulayForceStress::cal_pulay_fs(fvl_dphi, svl_dphi, *dm, ucell, pelec->pot, gint, isforce, isstress, false/*reset dm to gint*/);

source/module_hamilt_lcao/hamilt_lcaodft/FORCE_k.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,6 @@ void Force_LCAO<std::complex<double>>::allocate(const Parallel_Orbitals& pv,
131131
&GlobalC::GridD,
132132
nullptr); // delete lm.Hloc_fixedR
133133

134-
// calculate dVnl=<phi|dVnl|dphi> in LCAO
135-
LCAO_domain::build_Nonlocal_mu_new(pv,
136-
fsr,
137-
nullptr,
138-
cal_deri,
139-
GlobalC::ucell,
140-
orb,
141-
*(two_center_bundle.overlap_orb_beta),
142-
&GlobalC::GridD);
143-
144134
// calculate asynchronous S matrix to output for Hefei-NAMD
145135
if (PARAM.inp.cal_syns)
146136
{
@@ -329,7 +319,7 @@ void Force_LCAO<std::complex<double>>::ftable(const bool isforce,
329319
// vl_dphi
330320
PulayForceStress::cal_pulay_fs(fvl_dphi, svl_dphi, *dm, ucell, pelec->pot, gint, isforce, isstress, false/*reset dm to gint*/);
331321

332-
this->cal_fvnl_dbeta(dm,
322+
/*this->cal_fvnl_dbeta(dm,
333323
pv,
334324
ucell,
335325
orb,
@@ -338,7 +328,7 @@ void Force_LCAO<std::complex<double>>::ftable(const bool isforce,
338328
isforce,
339329
isstress,
340330
fvnl_dbeta,
341-
svnl_dbeta);
331+
svnl_dbeta);*/
342332

343333
#ifdef __DEEPKS
344334
if (PARAM.inp.deepks_scf)

0 commit comments

Comments
 (0)