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