1+ #include " surchem.h"
2+ #include " ../module_base/timer.h"
3+
4+ void force_cor_one (const UnitCell &cell, ModulePW::PW_Basis* rho_basis , ModuleBase::matrix& forcesol)
5+ {
6+
7+
8+ // delta phi multiply by the derivative of nuclear charge density with respect to the positions
9+ std::complex <double > *N = new std::complex <double >[rho_basis->npw ];
10+ std::complex <double > *vloc_at = new std::complex <double >[rho_basis->npw ];
11+ std::complex <double > *delta_phi_g = new complex <double >[rho_basis->npw ];
12+ // ModuleBase::GlobalFunc::ZEROS(delta_phi_g, rho_basis->npw);
13+
14+ rho_basis->real2recip (GlobalC::solvent_model.delta_phi , delta_phi_g);
15+ // GlobalC::UFFT.ToReciSpace(GlobalC::solvent_model.delta_phi, delta_phi_g,rho_basis);
16+ double Ael=0 ;double Ael1 = 0 ;
17+ // ModuleBase::GlobalFunc::ZEROS(vg, ngmc);
18+ int iat = 0 ;
19+
20+ for (int it = 0 ;it < cell.ntype ;it++)
21+ {
22+ for (int ia = 0 ;ia < cell.atoms [it].na ; ia++)
23+ {
24+ for (int ig = 0 ; ig < rho_basis->npw ; ig++)
25+ {
26+ complex <double > phase = exp ( ModuleBase::NEG_IMAG_UNIT *ModuleBase::TWO_PI * ( rho_basis->gcar [ig] * cell.atoms [it].tau [ia]));
27+ // vloc for each atom
28+ vloc_at[ig] = GlobalC::ppcell.vloc (it, rho_basis->ig2igg [ig]) * phase;
29+ if (rho_basis->ig_gge0 == ig)
30+ {
31+ N[ig] = GlobalC::ucell.atoms [it].zv / GlobalC::ucell.omega ;
32+ }
33+ else
34+ {
35+ const double fac = ModuleBase::e2 * ModuleBase::FOUR_PI /
36+ (cell.tpiba2 * rho_basis->gg [ig]);
37+
38+ N[ig] = -vloc_at[ig] / fac;
39+ }
40+
41+ // force for each atom
42+ forcesol (iat, 0 ) += rho_basis->gcar [ig][0 ] * imag (conj (delta_phi_g[ig]) * N[ig]);
43+ forcesol (iat, 1 ) += rho_basis->gcar [ig][1 ] * imag (conj (delta_phi_g[ig]) * N[ig]);
44+ forcesol (iat, 2 ) += rho_basis->gcar [ig][2 ] * imag (conj (delta_phi_g[ig]) * N[ig]);
45+ }
46+
47+ forcesol (iat, 0 ) *= (GlobalC::ucell.tpiba * GlobalC::ucell.omega );
48+ forcesol (iat, 1 ) *= (GlobalC::ucell.tpiba * GlobalC::ucell.omega );
49+ forcesol (iat, 2 ) *= (GlobalC::ucell.tpiba * GlobalC::ucell.omega );
50+ // unit Ry/Bohr
51+ forcesol (iat, 0 ) *= 2 ;
52+ forcesol (iat, 1 ) *= 2 ;
53+ forcesol (iat, 2 ) *= 2 ;
54+
55+ // cout<<"Force1"<<iat<<":"<<" "<<forcesol(iat, 0)<<" "<<forcesol(iat, 1)<<" "<<forcesol(iat, 2)<<endl;
56+
57+ ++iat;
58+ }
59+ }
60+
61+ delete[] vloc_at;
62+ delete[] N;
63+ delete[] delta_phi_g;
64+
65+ }
66+
67+ void force_cor_two (const UnitCell &cell, ModulePW::PW_Basis* rho_basis , ModuleBase::matrix& forcesol)
68+ {
69+
70+ complex <double > *n_pseudo = new complex <double >[rho_basis->npw ];
71+ ModuleBase::GlobalFunc::ZEROS (n_pseudo,rho_basis->npw );
72+
73+ // GlobalC::solvent_model.gauss_charge(cell, pwb, n_pseudo);
74+
75+ double *Vcav_sum = new double [rho_basis->nrxx ];
76+ ModuleBase::GlobalFunc::ZEROS (Vcav_sum, rho_basis->nrxx );
77+ std::complex <double > *Vcav_g = new complex <double >[rho_basis->npw ];
78+ std::complex <double > *Vel_g = new complex <double >[rho_basis->npw ];
79+ ModuleBase::GlobalFunc::ZEROS (Vcav_g, rho_basis->npw );
80+ ModuleBase::GlobalFunc::ZEROS (Vel_g, rho_basis->npw );
81+ for (int is=0 ; is<GlobalV::NSPIN; is++)
82+ {
83+ for (int ir=0 ; ir<rho_basis->nrxx ; ir++)
84+ {
85+ Vcav_sum[ir] += GlobalC::solvent_model.Vcav (is, ir);
86+ }
87+ }
88+
89+ rho_basis->real2recip (Vcav_sum, Vcav_g);
90+ rho_basis->real2recip (GlobalC::solvent_model.epspot , Vel_g);
91+
92+ int iat = 0 ;
93+ double Ael1 = 0 ;
94+ for (int it = 0 ;it < cell.ntype ;it++)
95+ {
96+ double RCS = GlobalC::solvent_model.GetAtom .atom_RCS [cell.atoms [it].psd ];
97+ double sigma_rc_k = RCS / 2.5 ;
98+ for (int ia = 0 ;ia < cell.atoms [it].na ;ia++)
99+ {
100+ // cell.atoms[0].tau[0].z = 3.302;
101+ // cout<<cell.atoms[it].tau[ia]<<endl;
102+ ModuleBase::GlobalFunc::ZEROS (n_pseudo, rho_basis->npw );
103+ for (int ig = 0 ; ig < rho_basis->npw ; ig++)
104+ {
105+ // G^2
106+ double gg = rho_basis->gg [ig];
107+ gg = gg * cell.tpiba2 ;
108+ complex <double > phase = exp ( ModuleBase::NEG_IMAG_UNIT *ModuleBase::TWO_PI * ( rho_basis->gcar [ig] * cell.atoms [it].tau [ia]));
109+
110+ n_pseudo[ig].real ((GlobalC::solvent_model.GetAtom .atom_Z [cell.atoms [it].psd ] - cell.atoms [it].zv ) * phase.real ()
111+ * exp (-0.5 * gg * (sigma_rc_k * sigma_rc_k)));
112+ n_pseudo[ig].imag ((GlobalC::solvent_model.GetAtom .atom_Z [cell.atoms [it].psd ] - cell.atoms [it].zv ) * phase.imag ()
113+ * exp (-0.5 * gg * (sigma_rc_k * sigma_rc_k)));
114+ }
115+
116+ for (int ig = 0 ; ig < rho_basis->npw ; ig++)
117+ {
118+ n_pseudo[ig] /= cell.omega ;
119+ }
120+ for (int ig = 0 ; ig < rho_basis->npw ; ig++)
121+ {
122+ forcesol (iat, 0 ) -= rho_basis->gcar [ig][0 ] * imag (conj (Vcav_g[ig]+Vel_g[ig]) * n_pseudo[ig]);
123+ forcesol (iat, 1 ) -= rho_basis->gcar [ig][1 ] * imag (conj (Vcav_g[ig]+Vel_g[ig]) * n_pseudo[ig]);
124+ forcesol (iat, 2 ) -= rho_basis->gcar [ig][2 ] * imag (conj (Vcav_g[ig]+Vel_g[ig]) * n_pseudo[ig]);
125+ }
126+
127+ forcesol (iat, 0 ) *= (GlobalC::ucell.tpiba * GlobalC::ucell.omega );
128+ forcesol (iat, 1 ) *= (GlobalC::ucell.tpiba * GlobalC::ucell.omega );
129+ forcesol (iat, 2 ) *= (GlobalC::ucell.tpiba * GlobalC::ucell.omega );
130+ // eV/Ang
131+ forcesol (iat, 0 ) *= 2 ;
132+ forcesol (iat, 1 ) *= 2 ;
133+ forcesol (iat, 2 ) *= 2 ;
134+
135+ // cout<<"Force2"<<iat<<":"<<" "<<forcesol(iat, 0)<<" "<<forcesol(iat, 1)<<" "<<forcesol(iat, 2)<<endl;
136+
137+ ++iat;
138+ }
139+ }
140+
141+ delete[] n_pseudo;
142+ delete[] Vcav_sum;
143+ delete[] Vcav_g;
144+ delete[] Vel_g;
145+
146+ }
147+
148+ void surchem::cal_force_sol (const UnitCell &cell, ModulePW::PW_Basis* rho_basis , ModuleBase::matrix& forcesol)
149+ {
150+ ModuleBase::TITLE (" surchem" , " cal_force_sol" );
151+ ModuleBase::timer::tick (" surchem" , " cal_force_sol" );
152+
153+ int nat = GlobalC::ucell.nat ;
154+ ModuleBase::matrix force1 (nat, 3 );
155+ ModuleBase::matrix force2 (nat, 3 );
156+
157+ force_cor_one (cell, rho_basis,force1);
158+ force_cor_two (cell, rho_basis,force2);
159+
160+ int iat = 0 ;
161+ for (int it = 0 ;it < GlobalC::ucell.ntype ;it++)
162+ {
163+ for (int ia = 0 ;ia < GlobalC::ucell.atoms [it].na ;ia++)
164+ {
165+ for (int ipol = 0 ; ipol < 3 ; ipol++)
166+ {
167+ forcesol (iat, ipol) = 0.5 *force1 (iat, ipol) + force2 (iat, ipol);
168+ }
169+
170+ ++iat;
171+ }
172+ }
173+
174+ Parallel_Reduce::reduce_double_pool (forcesol.c , forcesol.nr * forcesol.nc );
175+ ModuleBase::timer::tick (" surchem" , " cal_force_sol" );
176+ return ;
177+ }
0 commit comments