11#include " bfgs.h"
22#include " module_hamilt_pw/hamilt_pwdft/global.h"
33#include " module_base/matrix3.h"
4- #include " module_relax/relax_old/ions_move_basic.h"
54#include " module_parameter/parameter.h"
65#include " ions_move_basic.h"
76
87
8+
9+
10+
911void BFGS::allocate (const int _size) // initialize H0、H、pos0、force0、force
1012{
1113 alpha=70 ;// relax_scale_force
@@ -22,18 +24,18 @@ void BFGS::allocate(const int _size) // initialize H0、H、pos0、force0、forc
2224 }
2325 pos = std::vector<std::vector<double >> (size, std::vector<double >(3 , 0.0 ));
2426 pos0 = std::vector<double >(3 *size, 0.0 );
27+ pos_taud = std::vector<std::vector<double >> (size, std::vector<double >(3 , 0.0 ));
28+ pos_taud0 = std::vector<double >(3 *size, 0.0 );
2529 dpos = std::vector<std::vector<double >>(size, std::vector<double >(3 , 0.0 ));
2630 force0 = std::vector<double >(3 *size, 0.0 );
2731 force = std::vector<std::vector<double >>(size, std::vector<double >(3 , 0.0 ));
28- steplength = std::vector<double >(size, 0.0 );
29- this ->GetPos (GlobalC::ucell,pos);
30-
31-
32+ steplength = std::vector<double >(size, 0.0 );
3233}
33-
3434void BFGS::relax_step (ModuleBase::matrix _force,UnitCell& ucell)
3535{
3636 // std::cout<<"enter Step"<<std::endl;
37+ GetPos (ucell,pos);
38+ GetPostaud (ucell,pos_taud);
3739 ucell.ionic_position_updated = true ;
3840 for (int i = 0 ; i < _force.nr ; i++)
3941 {
@@ -45,27 +47,24 @@ void BFGS::relax_step(ModuleBase::matrix _force,UnitCell& ucell)
4547 }
4648 // std::cout<<std::endl;
4749 }
48- // std::cout<<"enter Step0"<<std::endl;
49- // std::cout<<size<<std::endl;
50- // GetPos(ucell);
51- this ->PrepareStep (force,pos,H,pos0,force0,steplength,dpos);
52- // std::cout<<"enter Step1"<<std::endl;
50+ this ->PrepareStep (force,pos,H,pos0,force0,steplength,dpos,ucell);
5351 this ->DetermineStep (steplength,dpos,maxstep);
5452
55- // std::cout<<"enter Step2 "<<std::endl;
56- /* for(int i=0;i<size;i++)
53+ /* std::cout<<"dpos "<<std::endl;
54+ for(int i=0;i<size;i++)
5755 {
5856 for(int j=0;j<3;j++)
5957 {
6058 std::cout<<dpos[i][j]<<' ';
6159 }
6260 std::cout<<std::endl;
6361 }*/
62+
6463 this ->UpdatePos (ucell);
65- // std::cout<<"enter Step3"<<std::endl;
6664 this ->IsRestrain (dpos);
65+ this ->CalculateLargestGrad (_force,ucell);
66+
6767}
68-
6968void BFGS::GetPos (UnitCell& ucell,std::vector<std::vector<double >>& pos)
7069{
7170 int k=0 ;
@@ -81,15 +80,27 @@ void BFGS::GetPos(UnitCell& ucell,std::vector<std::vector<double>>& pos)
8180 }
8281}
8382
83+ void BFGS::GetPostaud (UnitCell& ucell,std::vector<std::vector<double >>& pos_taud)
84+ {
85+ int k=0 ;
86+ for (int i=0 ;i<ucell.ntype ;i++)
87+ {
88+ for (int j=0 ;j<ucell.atoms [i].na ;j++)
89+ {
90+ pos_taud[k+j][0 ]=ucell.atoms [i].taud [j].x ;
91+ pos_taud[k+j][1 ]=ucell.atoms [i].taud [j].y ;
92+ pos_taud[k+j][2 ]=ucell.atoms [i].taud [j].z ;
93+ }
94+ k+=ucell.atoms [i].na ;
95+ }
96+ }
97+
8498
85- void BFGS::PrepareStep (std::vector<std::vector<double >>& force,std::vector<std::vector<double >>& pos,std::vector<std::vector<double >>& H,std::vector<double >& pos0,std::vector<double >& force0,std::vector<double >& steplength,std::vector<std::vector<double >>& dpos)
99+ void BFGS::PrepareStep (std::vector<std::vector<double >>& force,std::vector<std::vector<double >>& pos,std::vector<std::vector<double >>& H,std::vector<double >& pos0,std::vector<double >& force0,std::vector<double >& steplength,std::vector<std::vector<double >>& dpos,UnitCell& ucell )
86100{
87- // std::cout<<"enter prepareStep0"<<std::endl;
88101 std::vector<double > changedforce = this ->ReshapeMToV (force);
89102 std::vector<double > changedpos = this ->ReshapeMToV (pos);
90- // std::cout<<"enter prepareStep1"<<std::endl;
91- this ->Update (changedpos, changedforce,H);
92- // std::cout<<"enter prepareStep2"<<std::endl;
103+ this ->Update (changedpos, changedforce,H,ucell);
93104 /* for(int i = 0; i < 3*size; i++)
94105 {
95106 for(int j = 0; j < 3*size; j++)
@@ -98,12 +109,10 @@ void BFGS::PrepareStep(std::vector<std::vector<double>>& force,std::vector<std::
98109 }
99110 std::cout<<std::endl;
100111 }*/
112+
101113 // call dysev
102- // std::cout<<size<<std::endl;
103114 std::vector<double > omega (3 *size);
104- // std::cout<<"enter prepareStep3"<<std::endl;
105115 std::vector<double > work (3 *size*3 *size);
106- // std::cout<<"enter prepareStep4"<<std::endl;
107116 int lwork=3 *size*3 *size;
108117 int info;
109118 std::vector<double > H_flat;
@@ -115,7 +124,6 @@ void BFGS::PrepareStep(std::vector<std::vector<double>>& force,std::vector<std::
115124 int * ptr=&value;
116125 dsyev_ (" V" ," U" ,ptr,H_flat.data (),ptr,omega.data (),work.data (),&lwork,&info);
117126 std::vector<std::vector<double >> V (3 *size, std::vector<double >(3 *size, 0.0 ));
118- // std::cout<<"enter prepareStep5"<<std::endl;
119127 for (int i = 0 ; i < 3 *size; i++)
120128 {
121129 for (int j = 0 ; j < 3 *size; j++)
@@ -124,38 +132,27 @@ void BFGS::PrepareStep(std::vector<std::vector<double>>& force,std::vector<std::
124132 }
125133 }
126134
127-
128135 /* for(int i=0;i<3*size;i++)
129136 {
130137 std::cout<<omega[i]<<' ';
131138 }
132139 std::cout<<std::endl;*/
140+
133141 std::vector<double > a=this ->DotInMAndV2 (V, changedforce);
134142 for (int i = 0 ; i < a.size (); i++)
135143 {
136- if (omega[i]>0 )
144+ a[i]/=std::abs (omega[i]);
145+ /* if(omega[i]>0)
137146 {
138147 a[i] /= omega[i];
139148 }
140149 else if(omega[i]<0)
141150 {
142151 a[i] /= (-omega[i]);
143- }
144-
152+ }*/
145153 }
146-
147154 std::vector<double > tmpdpos = this ->DotInMAndV1 (V, a);
148-
149-
150155 dpos = this ->ReshapeVToM (tmpdpos);
151- /* for(int i=0;i<size;i++)
152- {
153- for(int j=0;j<3;j++)
154- {
155- std::cout<<dpos[i][j]<<' ';
156- }
157- std::cout<<std::endl;
158- }*/
159156 for (int i = 0 ; i < size; i++)
160157 {
161158 double k = 0 ;
@@ -166,29 +163,77 @@ void BFGS::PrepareStep(std::vector<std::vector<double>>& force,std::vector<std::
166163 steplength[i] = sqrt (k);
167164 }
168165 pos0 = this ->ReshapeMToV (pos);
166+ pos_taud0=this ->ReshapeMToV (pos_taud);
169167 force0 = this ->ReshapeMToV (force);
170168}
171169
172- void BFGS::Update (std::vector<double > pos, std::vector<double > force,std::vector<std::vector<double >>& H)
170+ void BFGS::Update (std::vector<double > pos, std::vector<double > force,std::vector<std::vector<double >>& H,UnitCell& ucell )
173171{
174172 if (sign)
175173 {
176174 sign=false ;
177175 return ;
178176 }
179- /* std::cout<<"PrintPos"<<std::endl ;
177+ std::vector< double > dpos = this -> VSubV ( ReshapeMToV (pos_taud), pos_taud0) ;
180178 for (int i=0 ;i<3 *size;i++)
181179 {
182- std::cout<<pos[i]<<' ';
180+ double shortest_move = dpos[i];
181+ // dpos[i]/=ModuleBase::BOHR_TO_A;
182+ // dpos[i]/=ucell.lat0;
183+ for (int cell = -1 ; cell <= 1 ; ++cell)
184+ {
185+ const double now_move = dpos[i] + cell;
186+ if (std::abs (now_move) < std::abs (shortest_move))
187+ {
188+ shortest_move = now_move;
189+ }
190+ }
191+ // shortest_move=shortest_move*ModuleBase::BOHR_TO_A*ucell.lat0;
192+ dpos[i]=shortest_move;
183193 }
184- std::cout<<std::endl;
185- std::cout<<"PrintPos0"<<std::endl;
194+ std::vector<std::vector<double >> c=ReshapeVToM (dpos);
195+ for (int iat=0 ; iat<size; iat++)
196+ {
197+ // Cartesian coordinate
198+ // convert from Angstrom to unit of latvec (Bohr)
199+
200+ // convert unit
201+ ModuleBase::Vector3<double > move_ion_cart;
202+ move_ion_cart.x = c[iat][0 ] *ModuleBase::BOHR_TO_A * ucell.lat0 ;
203+ move_ion_cart.y = c[iat][1 ] * ModuleBase::BOHR_TO_A * ucell.lat0 ;
204+ move_ion_cart.z = c[iat][2 ] * ModuleBase::BOHR_TO_A * ucell.lat0 ;
205+ /* std::cout<<"moveioncart"<<std::endl;
206+ std::cout<<move_ion_cart.x<<' ';
207+ std::cout<<move_ion_cart.y<<' ';
208+ std::cout<<move_ion_cart.z<<' ';
209+ std::cout<<std::endl;*/
210+
211+
212+ // convert pos
213+ ModuleBase::Vector3<double > move_ion_dr = move_ion_cart* ucell.latvec ;
214+ int it = ucell.iat2it [iat];
215+ int ia = ucell.iat2ia [iat];
216+ Atom* atom = &ucell.atoms [it];
217+
218+ if (atom->mbl [ia].x == 1 )
219+ {
220+ dpos[iat * 3 ] = move_ion_dr.x ;
221+ }
222+ if (atom->mbl [ia].y == 1 )
223+ {
224+ dpos[iat * 3 + 1 ] = move_ion_dr.y ;
225+ }
226+ if (atom->mbl [ia].z == 1 )
227+ {
228+ dpos[iat * 3 + 2 ] = move_ion_dr.z ;
229+ }
230+ }
231+ /* std::cout<<"PrintDpos"<<std::endl;
186232 for(int i=0;i<3*size;i++)
187233 {
188- std::cout<<pos0 [i]<<' ';
234+ std::cout<<dpos [i]<<' ';
189235 }
190236 std::cout<<std::endl;*/
191- std::vector<double > dpos = this ->VSubV (pos, pos0);
192237 if (*max_element (dpos.begin (), dpos.end ()) < 1e-7 )
193238 {
194239 return ;
@@ -220,7 +265,18 @@ void BFGS::DetermineStep(std::vector<double> steplength,std::vector<std::vector<
220265
221266void BFGS::UpdatePos (UnitCell& ucell)
222267{
223- double move_ion[3 *size];
268+ double a[3 *size];
269+ for (int i=0 ;i<size;i++)
270+ {
271+ for (int j=0 ;j<3 ;j++)
272+ {
273+ a[i*3 +j]=pos[i][j]+dpos[i][j];
274+ a[i*3 +j]/=ModuleBase::BOHR_TO_A;
275+ }
276+ }
277+ ucell.update_pos_tau (a);
278+
279+ /* double move_ion[3*size];
224280 ModuleBase::zeros(move_ion, size*3);
225281
226282 for(int iat=0; iat<size; iat++)
@@ -233,12 +289,17 @@ void BFGS::UpdatePos(UnitCell& ucell)
233289 move_ion_cart.x = dpos[iat][0] / ModuleBase::BOHR_TO_A / ucell.lat0;
234290 move_ion_cart.y = dpos[iat][1] / ModuleBase::BOHR_TO_A / ucell.lat0;
235291 move_ion_cart.z = dpos[iat][2] / ModuleBase::BOHR_TO_A / ucell.lat0;
292+ std::cout<<"moveioncart"<<std::endl;
293+ std::cout<<move_ion_cart.x<<' ';
294+ std::cout<<move_ion_cart.y<<' ';
295+ std::cout<<move_ion_cart.z<<' ';
296+ std::cout<<std::endl;
236297
237298 //convert to Direct coordinate
238299 //note here the old GT is used
239300
240301 //convert pos
241- ModuleBase::Vector3<double > move_ion_dr = move_ion_cart * ucell.GT ;
302+ ModuleBase::Vector3<double> move_ion_dr = move_ion_cart* ucell.GT;
242303
243304
244305 int it = ucell.iat2it[iat];
@@ -258,8 +319,43 @@ void BFGS::UpdatePos(UnitCell& ucell)
258319 move_ion[iat * 3 + 2] = move_ion_dr.z ;
259320 }
260321 }
261- ucell.update_pos_taud (move_ion);
262- pos = this ->MAddM (pos, dpos);
322+ std::cout<<"move_ion_dr"<<std::endl;
323+ for(int i=0;i<3*size;i++)
324+ {
325+ std::cout<<move_ion[i]<<' ';
326+ }
327+ std::cout<<std::endl;
328+ std::cout<<"printtau"<<std::endl;
329+ for(int i=0;i<ucell.ntype;i++)
330+ {
331+ for(int j=0;j<ucell.atoms[i].na;j++)
332+ {
333+ std::cout<<ucell.atoms[i].tau[j].x<<' ';
334+ std::cout<<ucell.atoms[i].tau[j].y<<' ';
335+ std::cout<<ucell.atoms[i].tau[j].z<<' ';
336+ std::cout<<ucell.atoms[i].taud[j].x<<' ';
337+ std::cout<<ucell.atoms[i].taud[j].y<<' ';
338+ std::cout<<ucell.atoms[i].taud[j].z<<' ';
339+ }
340+ std::cout<<std::endl;
341+ }
342+ //ucell.update_pos_taud(move_ion);
343+
344+ std::cout<<"printtau"<<std::endl;
345+ for(int i=0;i<ucell.ntype;i++)
346+ {
347+ for(int j=0;j<ucell.atoms[i].na;j++)
348+ {
349+ std::cout<<ucell.atoms[i].tau[j].x<<' ';
350+ std::cout<<ucell.atoms[i].tau[j].y<<' ';
351+ std::cout<<ucell.atoms[i].tau[j].z<<' ';
352+ std::cout<<ucell.atoms[i].taud[j].x<<' ';
353+ std::cout<<ucell.atoms[i].taud[j].y<<' ';
354+ std::cout<<ucell.atoms[i].taud[j].z<<' ';
355+ }
356+ std::cout<<std::endl;
357+ }
358+ //pos = this->MAddM(pos, dpos);*/
263359}
264360
265361void BFGS::IsRestrain (std::vector<std::vector<double >>& dpos)
@@ -284,9 +380,48 @@ void BFGS::IsRestrain(std::vector<std::vector<double>>& dpos)
284380 }
285381 }
286382 }
287- // std::cout<<a<<std::endl;
383+ std::cout<<" max dpos" <<std::endl;
384+ std::cout<<a<<std::endl;
288385 Ions_Move_Basic::converged = a<0.00001 ;
289386}
387+
388+ void BFGS::CalculateLargestGrad (ModuleBase::matrix _force,UnitCell& ucell)
389+ {
390+ std::vector<double > grad= std::vector<double >(3 *size, 0.0 );
391+ int iat = 0 ;
392+ for (int it = 0 ; it < ucell.ntype ; it++)
393+ {
394+ Atom *atom = &ucell.atoms [it];
395+ for (int ia = 0 ; ia < ucell.atoms [it].na ; ia++)
396+ {
397+ for (int ik = 0 ; ik < 3 ; ++ik)
398+ {
399+ if (atom->mbl [ia][ik])
400+ {
401+ grad[3 * iat + ik] = -_force (iat, ik) * ucell.lat0 ;
402+ }
403+ }
404+ ++iat;
405+ }
406+ }
407+ Ions_Move_Basic::largest_grad = 0.0 ;
408+ for (int i = 0 ; i < 3 *size; i++)
409+ {
410+ if (Ions_Move_Basic::largest_grad < std::abs (grad[i]))
411+ {
412+ Ions_Move_Basic::largest_grad = std::abs (grad[i]);
413+ }
414+ }
415+ Ions_Move_Basic::largest_grad /= ucell.lat0 ;
416+ if (PARAM.inp .out_level == " ie" )
417+ {
418+ std::cout << " LARGEST GRAD (eV/A) : " << Ions_Move_Basic::largest_grad * ModuleBase::Ry_to_eV / 0.529177
419+ << std::endl;
420+ }
421+
422+ }
423+
424+
290425// matrix methods
291426
292427std::vector<double > BFGS::ReshapeMToV (std::vector<std::vector<double >> matrix)
0 commit comments