Skip to content

Commit 5f9d472

Browse files
wenfei-liwenfei-liQianruipku
authored
Feature : add paw_nl_force (not tested yet) (#3279)
* update version of libpaw_interface * Feature : add paw_nl_force * update ut for paw --------- Co-authored-by: wenfei-li <liwenfei@gmail.com> Co-authored-by: Qianrui Liu <76200646+Qianruipku@users.noreply.github.com>
1 parent 68d54c8 commit 5f9d472

File tree

14 files changed

+55461
-10338
lines changed

14 files changed

+55461
-10338
lines changed

deps/libpaw_interface

source/module_cell/module_paw/paw_atom.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Paw_Atom
1919

2020
//pass <psi|ptilde> from outside and saves it
2121
void set_ca(std::vector<std::complex<double>> & ca_in, const double weight_in);
22+
void set_dca(std::vector<std::vector<std::complex<double>>> & dca_in, const double weight_in);
2223

2324
void init_rhoij(); //set rhoij according to occupation number in xml file
2425

@@ -50,6 +51,7 @@ class Paw_Atom
5051

5152
std::vector<std::complex<double>> ca; //coefficients <psi|ptilde> for a given psi
5253
std::vector<std::vector<double>> rhoij; //on-site density matrix, upper triangular
54+
std::vector<std::vector<std::complex<double>>> dca; // d/dR_I <psi|ptilde>
5355

5456
std::vector<std::vector<double>> dij; //nonlocal pseudopotential strength
5557
std::vector<double> sij; //<phi|phi> - <phitilde|phitilde>

source/module_cell/module_paw/paw_cell.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,21 @@ void Paw_Cell::set_paw_k(
210210
{
211211
gnorm[ipw] = std::sqrt(kpg[ipw][0]*kpg[ipw][0] + kpg[ipw][1]*kpg[ipw][1] + kpg[ipw][2]*kpg[ipw][2]) * tpiba;
212212
}
213+
214+
std::complex<double> i_cplx = (0.0,1.0);
215+
// ikpg : i (k+G)
216+
//if(GlobalV::CAL_FORCE || GlobalV::CAL_STRESS)
217+
{
218+
ikpg.resize(npw);
219+
for(int ipw = 0; ipw < npw; ipw ++)
220+
{
221+
ikpg[ipw].resize(3);
222+
for(int i = 0; i < 3; i ++)
223+
{
224+
ikpg[ipw][i] = kpg[ipw][i] * tpiba * i_cplx;
225+
}
226+
}
227+
}
213228
}
214229

215230
void Paw_Cell::set_isk(const int nk, const int * isk_in)
@@ -665,4 +680,81 @@ void Paw_Cell::paw_nl_psi(const int mode, const std::complex<double> * psi, std:
665680
}
666681
}
667682
}
683+
}
684+
685+
void Paw_Cell::paw_nl_force(const std::complex<double> * psi, const double * epsilon, const double * weight, const int nbands , double * force)
686+
{
687+
ModuleBase::TITLE("Paw_Cell","paw_nl_force");
688+
689+
for(int iband = 0; iband < nbands; iband ++)
690+
{
691+
for(int iat = 0; iat < nat; iat ++)
692+
{
693+
// ca : <ptilde(G)|psi(G)>
694+
// = \sum_G [\int f(r)r^2j_l(r)dr] * [(-i)^l] * [ylm(\hat{G})] * [exp(-GR_I)] *psi(G)
695+
// = \sum_ipw ptilde * fact * ylm * sk * psi (in the code below)
696+
// This is what is called 'becp' in nonlocal pp
697+
std::vector<std::complex<double>> ca;
698+
std::vector<std::vector<std::complex<double>>> dca;
699+
700+
const int it = atom_type[iat];
701+
const int nproj = paw_element_list[it].get_mstates();
702+
const int proj_start = start_iprj_ia[iat];
703+
704+
ca.resize(nproj);
705+
dca.resize(3);
706+
for(int i = 0; i < 3; i ++)
707+
{
708+
dca[i].resize(nproj);
709+
}
710+
711+
for(int iproj = 0; iproj < nproj; iproj ++)
712+
{
713+
ca[iproj] = 0.0;
714+
dca[0][iproj] = 0.0;
715+
dca[1][iproj] = 0.0;
716+
dca[2][iproj] = 0.0;
717+
718+
// consider use blas subroutine for this part later
719+
for(int ipw = 0; ipw < npw; ipw ++)
720+
{
721+
std::complex<double> overlp = psi[ipw] * std::conj(vkb[iproj+proj_start][ipw]);
722+
ca[iproj] += overlp;
723+
dca[0][iproj] += overlp * ikpg[ipw][0];
724+
dca[1][iproj] += overlp * ikpg[ipw][1];
725+
dca[2][iproj] += overlp * ikpg[ipw][2];
726+
}
727+
}
728+
729+
#ifdef __MPI
730+
Parallel_Reduce::reduce_pool(ca.data(), nproj);
731+
Parallel_Reduce::reduce_pool(dca[0].data(), nproj);
732+
Parallel_Reduce::reduce_pool(dca[1].data(), nproj);
733+
Parallel_Reduce::reduce_pool(dca[2].data(), nproj);
734+
#endif
735+
// sum_ij (D_ij - epsilon_n O_ij) ca_j
736+
std::vector<std::complex<double>> v_ca;
737+
v_ca.resize(nproj);
738+
739+
for(int iproj = 0; iproj < nproj; iproj ++)
740+
{
741+
v_ca[iproj] = 0.0;
742+
for(int jproj = 0; jproj < nproj; jproj ++)
743+
{
744+
double coeff = paw_atom_list[iat].get_dij()[current_spin][iproj*nproj+jproj] -
745+
paw_atom_list[iat].get_sij()[iproj*nproj+jproj] * epsilon[iband];
746+
v_ca[iproj] += coeff * ca[jproj];
747+
}
748+
}
749+
750+
// force += conjg(v_ca[iproj]) * d_ca[iproj]
751+
// \sum_i ptilde_{iproj}(G) v_ca[iproj]
752+
for(int iproj = 0; iproj < nproj; iproj ++)
753+
{
754+
force[iat*3] += (std::conj(v_ca[iproj]) * dca[0][iproj]).real();
755+
force[iat*3+1] += (std::conj(v_ca[iproj]) * dca[1][iproj]).real();
756+
force[iat*3+2] += (std::conj(v_ca[iproj]) * dca[2][iproj]).real();
757+
}
758+
}
759+
}
668760
}

source/module_cell/module_paw/paw_cell.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ class Paw_Cell
162162
// I'd rather also calculate it once and save it
163163
std::vector<double> gnorm;
164164

165+
// i(k+G), used in force calculation
166+
std::vector<std::vector<std::complex<double>>> ikpg;
167+
165168
void set_ylm(const int npw_in, const double ** kpg);
166169

167170
std::vector<int> isk;
@@ -176,6 +179,9 @@ class Paw_Cell
176179
// mode = 0 : V_{NL}|psi>, mode = 1 : (S+I)|psi>
177180
void paw_nl_psi(const int mode, const std::complex<double> * psi, std::complex<double> * vnlpsi);
178181

182+
183+
void paw_nl_force(const std::complex<double> * psi, const double * epsilon, const double * weight, const int nbands , double * force);
184+
179185
// set by providing dij explicitly
180186
void set_dij(const int iat, double** dij_in){paw_atom_list[iat].set_dij(dij_in);}
181187
// set by extracting dij from libpaw_interface

source/module_cell/module_paw/test/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,8 @@ AddTest(
4545
)
4646
add_dependencies(Test_Paw4 libpaw_interface)
4747

48+
AddTest(
49+
TARGET Test_Paw5
50+
LIBS ${math_libs} base device
51+
SOURCES test_paw5.cpp ../paw_element.cpp ../paw_sphbes.cpp ../paw_cell.cpp ../paw_atom.cpp
52+
)

0 commit comments

Comments
 (0)