diff --git a/docs/advanced/input_files/input-main.md b/docs/advanced/input_files/input-main.md index 32d4eafc53..6f4986b4dd 100644 --- a/docs/advanced/input_files/input-main.md +++ b/docs/advanced/input_files/input-main.md @@ -113,6 +113,7 @@ - [npart\_sto](#npart_sto) - [Geometry Relaxation](#geometry-relaxation) - [relax\_method](#relax_method) + - [cp2k](#cp2k) - [relax\_new](#relax_new) - [relax\_scale\_force](#relax_scale_force) - [relax\_nmax](#relax_nmax) diff --git a/source/source_io/input_conv.cpp b/source/source_io/input_conv.cpp index 279c09c405..a0dd1618de 100644 --- a/source/source_io/input_conv.cpp +++ b/source/source_io/input_conv.cpp @@ -190,6 +190,7 @@ void Input_Conv::Convert() Ions_Move_Basic::relax_bfgs_init = PARAM.inp.relax_bfgs_init; Ions_Move_Basic::out_stru = PARAM.inp.out_stru; // mohan add 2012-03-23 Ions_Move_Basic::relax_method = PARAM.inp.relax_method; + Ions_Move_Basic::cp2k = PARAM.inp.cp2k; Lattice_Change_Basic::fixed_axes = PARAM.inp.fixed_axes; diff --git a/source/source_io/module_parameter/input_parameter.h b/source/source_io/module_parameter/input_parameter.h index 64392c8c34..5b75f75ebf 100644 --- a/source/source_io/module_parameter/input_parameter.h +++ b/source/source_io/module_parameter/input_parameter.h @@ -152,6 +152,7 @@ struct Input_para // ============== #Parameters (4.Relaxation) =========================== std::vector relax_method = {"cg","1"}; ///< methods to move_ion: sd, bfgs, cg... + std::string cp2k = "none"; bool relax_new = true; bool relax = false; ///< allow relaxation along the specific direction double relax_scale_force = 0.5; diff --git a/source/source_io/read_input_item_relax.cpp b/source/source_io/read_input_item_relax.cpp index f8c3453893..793b32d45e 100644 --- a/source/source_io/read_input_item_relax.cpp +++ b/source/source_io/read_input_item_relax.cpp @@ -48,6 +48,20 @@ void ReadInput::item_relax() // }; // this->add_item(item); } + { + Input_Item item("cp2k"); + item.annotation = "x; y; z; none;"; + read_sync_string(input.cp2k); + item.check_value = [](const Input_Item& item, const Parameter& para) { + const std::vector cp2ks = {"x", "y", "z", "none"}; + if (std::find(cp2ks.begin(),cp2ks.end(), para.input.cp2k)==cp2ks.end()) + { + const std::string warningstr = nofound_str(cp2ks, "cp2k"); + ModuleBase::WARNING_QUIT("ReadInput", warningstr); + } + }; + this->add_item(item); + } { Input_Item item("relax_new"); item.annotation = "whether to use the new relaxation method"; diff --git a/source/source_relax/bfgs.cpp b/source/source_relax/bfgs.cpp index d105dc2791..e56d21c1fc 100644 --- a/source/source_relax/bfgs.cpp +++ b/source/source_relax/bfgs.cpp @@ -15,11 +15,11 @@ void BFGS::allocate(const int _size) size=_size; largest_grad=0.0; sign=true; - H = std::vector>(3*size, std::vector(3*size, 0.0)); + H = ModuleBase::matrix(3*size, 3*size); for (int i = 0; i < 3*size; ++i) { - H[i][i] = alpha; + H(i,i) = alpha; } pos = std::vector> (size, ModuleBase::Vector3(0.0, 0.0, 0.0)); @@ -114,7 +114,7 @@ void BFGS::GetPostaud(UnitCell& ucell, void BFGS::PrepareStep(std::vector>& force, std::vector>& pos, - std::vector>& H, + ModuleBase::matrix& H, std::vector& pos0, std::vector& force0, std::vector& steplength, @@ -133,20 +133,23 @@ void BFGS::PrepareStep(std::vector>& force, int info=0; std::vector H_flat; - for(const auto& row : H) + for(int i=0;i> V(3*size, std::vector(3*size, 0.0)); + ModuleBase::matrix V(3*size, 3*size); for(int i = 0; i < 3*size; i++) { for(int j = 0; j < 3*size; j++) { - V[j][i] = H_flat[3*size*i + j]; + V(j,i) = H_flat[3*size*i + j]; } } std::vector a=DotInMAndV2(V, changedforce); @@ -174,7 +177,7 @@ void BFGS::PrepareStep(std::vector>& force, void BFGS::Update(std::vector& pos, std::vector& force, - std::vector>& H, + ModuleBase::matrix& H, UnitCell& ucell) { if(sign) @@ -240,10 +243,10 @@ void BFGS::Update(std::vector& pos, double a = DotInVAndV(dpos, dforce); std::vector dg = DotInMAndV1(H, dpos); double b = DotInVAndV(dpos, dg); - std::vector> term1=OuterVAndV(dforce, dforce); - std::vector> term2=OuterVAndV(dg, dg); - std::vector> term3=MPlus(term1, a); - std::vector> term4=MPlus(term2, b); + ModuleBase::matrix term1=OuterVAndV(dforce, dforce); + ModuleBase::matrix term2=OuterVAndV(dg, dg); + ModuleBase::matrix term3=MPlus(term1, a); + ModuleBase::matrix term4=MPlus(term2, b); H = MSubM(H, term3); H = MSubM(H, term4); } diff --git a/source/source_relax/bfgs.h b/source/source_relax/bfgs.h index b8872c979f..2512d41e05 100644 --- a/source/source_relax/bfgs.h +++ b/source/source_relax/bfgs.h @@ -26,7 +26,7 @@ class BFGS int size;//number of atoms std::vector steplength;//the length of atoms displacement - std::vector> H;//Hessian matrix + ModuleBase::matrix H;//Hessian matrix std::vector force0;//force in previous step std::vector> force; std::vector pos0;//atom pos in previous step(cartesian coordinates) @@ -35,12 +35,12 @@ class BFGS std::vector> pos_taud; std::vector> dpos; - void PrepareStep(std::vector>& force,std::vector>& pos,std::vector>& H,std::vector& pos0,std::vector& force0,std::vector& steplength,std::vector>& dpos,int& size,UnitCell& ucell);//calculate the atomic displacement in one iteration step + void PrepareStep(std::vector>& force,std::vector>& pos,ModuleBase::matrix& H,std::vector& pos0,std::vector& force0,std::vector& steplength,std::vector>& dpos,int& size,UnitCell& ucell);//calculate the atomic displacement in one iteration step void IsRestrain();//check if converged void CalculateLargestGrad(const ModuleBase::matrix& _force,UnitCell& ucell); void GetPos(UnitCell& ucell,std::vector>& pos); void GetPostaud(UnitCell& ucell,std::vector>& pos_taud); - void Update(std::vector& pos, std::vector& force,std::vector>& H,UnitCell& ucell);//update hessian matrix + void Update(std::vector& pos, std::vector& force,ModuleBase::matrix& H,UnitCell& ucell);//update hessian matrix void DetermineStep(std::vector& steplength,std::vector>& dpos,double& maxstep);//normalize large atomic displacements based on maxstep void UpdatePos(UnitCell& ucell);//update ucell with the new coordinates diff --git a/source/source_relax/ions_move_basic.h b/source/source_relax/ions_move_basic.h index 8f03085028..d64fb6179f 100644 --- a/source/source_relax/ions_move_basic.h +++ b/source/source_relax/ions_move_basic.h @@ -22,6 +22,7 @@ extern double relax_bfgs_rmin; // min value of trust radius, extern double relax_bfgs_init; // initial value of trust radius, extern double best_xxx; // the last step length of cg , we use it as bfgs`s initial step length extern std::vector relax_method; // relaxation method, +extern std::string cp2k; extern int out_stru; // output the structure or not // funny way to pass this parameter, but nevertheless diff --git a/source/source_relax/lattice_change_basic.cpp b/source/source_relax/lattice_change_basic.cpp index d6cfaec9ef..198125fbac 100644 --- a/source/source_relax/lattice_change_basic.cpp +++ b/source/source_relax/lattice_change_basic.cpp @@ -16,6 +16,8 @@ double Lattice_Change_Basic::ediff = 0.0; double Lattice_Change_Basic::etot = 0.0; double Lattice_Change_Basic::etot_p = 0.0; +std::string Ions_Move_Basic::cp2k = "none"; + // double Lattice_Change_Basic::lattice_change_ini = 0.5; // default is 0.5 double Lattice_Change_Basic::lattice_change_ini = 0.01; // default is 0.5 std::string Lattice_Change_Basic::fixed_axes = "None"; @@ -83,6 +85,18 @@ void Lattice_Change_Basic::change_lattice(UnitCell &ucell, double *move, double for (int j = 0;j < 3;++j) { move_mat_t(j, i) = move[i * 3 + j] / ucell.lat0; //transpose + if(j==0&&Ions_Move_Basic::cp2k=="x") + { + move_mat_t(j, i) = 0.0; + } + if(j==1&&Ions_Move_Basic::cp2k=="y") + { + move_mat_t(j, i) = 0.0; + } + if (j==2&&Ions_Move_Basic::cp2k=="z") + { + move_mat_t(j, i) = 0.0; + } } } ModuleBase::matrix symm_move_mat_t = (move_mat_t * ucell.G.to_matrix());//symmetrize (latvec^{-1} * move_mat)^T @@ -97,7 +111,6 @@ void Lattice_Change_Basic::change_lattice(UnitCell &ucell, double *move, double } } } - if (ucell.lc[0] != 0) { ucell.latvec.e11 = (move[0] + lat[0]) / ucell.lat0; diff --git a/source/source_relax/lattice_change_basic.h b/source/source_relax/lattice_change_basic.h index 263c7bd5ca..7ca447fdb7 100644 --- a/source/source_relax/lattice_change_basic.h +++ b/source/source_relax/lattice_change_basic.h @@ -3,6 +3,7 @@ #include "source_base/matrix.h" #include "source_cell/unitcell.h" +#include "ions_move_basic.h" namespace Lattice_Change_Basic { diff --git a/source/source_relax/lbfgs.cpp b/source/source_relax/lbfgs.cpp index 31eaa2116a..84a0fd56ad 100644 --- a/source/source_relax/lbfgs.cpp +++ b/source/source_relax/lbfgs.cpp @@ -12,7 +12,6 @@ void LBFGS::allocate(const int _size) // initialize H0、H、pos0、force0、for size=_size; memory=100; iteration=0; - H = std::vector>(3*size, std::vector(3*size, 0.0)); H0=1/alpha; pos = std::vector> (size, ModuleBase::Vector3(0.0, 0.0, 0.0)); pos0 = std::vector(3*size, 0.0); @@ -59,7 +58,7 @@ void LBFGS::relax_step(const ModuleBase::matrix _force,UnitCell& ucell,const dou } k+=ucell.atoms[i].na; } - this->prepare_step(force,pos,H,pos0,force0,dpos,ucell,etot); + this->prepare_step(force,pos,pos0,force0,dpos,ucell,etot); this->determine_step(steplength,dpos,maxstep); this->update_pos(ucell); this->calculate_largest_grad(_force,ucell); @@ -100,7 +99,6 @@ void LBFGS::get_pos_taud(UnitCell& ucell,std::vector void LBFGS::prepare_step(std::vector>& force, std::vector>& pos, - std::vector>& H, std::vector& pos0, std::vector& force0, std::vector>& dpos, diff --git a/source/source_relax/lbfgs.h b/source/source_relax/lbfgs.h index 1ad929b722..30d6bb6879 100644 --- a/source/source_relax/lbfgs.h +++ b/source/source_relax/lbfgs.h @@ -50,7 +50,6 @@ class LBFGS ModuleESolver::ESolver* solver; ///< Structure solver std::vector steplength;//the length of atoms displacement - std::vector> H;//Hessian matrix std::vector force0;//force in previous step std::vector> force; std::vector pos0;//atom pos in previous step(cartesian coordinates) @@ -67,7 +66,6 @@ class LBFGS */ void prepare_step(std::vector>& force, std::vector>& pos, - std::vector>& H, std::vector& pos0, std::vector& force0, std::vector>& dpos, diff --git a/source/source_relax/matrix_methods.cpp b/source/source_relax/matrix_methods.cpp index 96079d55e1..fd59e70fdd 100644 --- a/source/source_relax/matrix_methods.cpp +++ b/source/source_relax/matrix_methods.cpp @@ -18,17 +18,17 @@ std::vector ReshapeMToV(std::vector>& matrix return result; } -std::vector> MAddM(std::vector>& a, - std::vector>& b) +ModuleBase::matrix MAddM(ModuleBase::matrix& a, + ModuleBase::matrix& b) { - assert(!a.empty() && !b.empty()); - assert(a.size() == b.size() && a[0].size() == b[0].size()); - std::vector> result = std::vector>(a.size(), std::vector(a[0].size(), 0.0)); - for(int i = 0; i < a.size(); i++) + assert(a.nr!=0 && a.nc!=0 && b.nr!=0 && b.nc!=0); + assert(a.nr == b.nr && a.nc == b.nc); + ModuleBase::matrix result = ModuleBase::matrix(a.nr, a.nc); + for(int i = 0; i < a.nr; i++) { - for(int j = 0; j < a[0].size(); j++) + for(int j = 0; j < a.nc; j++) { - result[i][j] = a[i][j] + b[i][j]; + result(i,j) = a(i,j) + b(i,j); } } return result; @@ -58,30 +58,30 @@ std::vector> ReshapeVToM(std::vector& matrix return result; } -std::vector DotInMAndV1(std::vector>& matrix, std::vector& vec) +std::vector DotInMAndV1(ModuleBase::matrix& matrix, std::vector& vec) { - assert(!matrix.empty()); - assert(matrix[0].size() == vec.size()); - std::vector result(matrix.size(), 0.0); + assert(matrix.nr!=0 && matrix.nc!=0); + assert(matrix.nc == vec.size()); + std::vector result(matrix.nr, 0.0); for(int i = 0; i < result.size(); i++) { for(int j = 0; j < vec.size(); j++) { - result[i] += matrix[i][j] * vec[j]; + result[i] += matrix(i,j) * vec[j]; } } return result; } -std::vector DotInMAndV2(std::vector>& matrix, std::vector& vec) +std::vector DotInMAndV2(ModuleBase::matrix& matrix, std::vector& vec) { - assert(!matrix.empty()); - assert(matrix.size() == vec.size()); - std::vector result(matrix.size(), 0.0); + assert(matrix.nr!=0 && matrix.nc!=0); + assert(matrix.nr == vec.size()); + std::vector result(matrix.nc, 0.0); for(int i = 0; i < result.size(); i++) { for(int j = 0; j < vec.size(); j++) { - result[i] += matrix[j][i] * vec[j]; + result[i] += matrix(j,i) * vec[j]; } } return result; @@ -98,45 +98,45 @@ double DotInVAndV(std::vector& vec1, std::vector& vec2) return result; } -std::vector> OuterVAndV(std::vector& a, std::vector& b) +ModuleBase::matrix OuterVAndV(std::vector& a, std::vector& b) { assert(a.size() == b.size()); - std::vector> result = std::vector>(a.size(), std::vector(b.size(), 0.0)); + ModuleBase::matrix result = ModuleBase::matrix(a.size(), b.size()); for(int i = 0; i < a.size(); i++) { for(int j = 0; j < b.size(); j++) { - result[i][j] = a[i] * b[j]; + result(i,j) = a[i] * b[j]; } } return result; } -std::vector> MPlus(std::vector>& a, double b) +ModuleBase::matrix MPlus(ModuleBase::matrix& a, double b) { - assert(!a.empty()); + assert(a.nr!=0 && a.nc!=0); assert(b != 0); - std::vector> result = std::vector>(a.size(), std::vector(a[0].size(), 0.0)); - for(int i = 0; i < a.size(); i++) + ModuleBase::matrix result = ModuleBase::matrix(a.nr, a.nc); + for(int i = 0; i < a.nr; i++) { - for(int j = 0; j < a[0].size(); j++) + for(int j = 0; j < a.nc; j++) { - result[i][j] = a[i][j] / b; + result(i,j) = a(i,j) / b; } } return result; } -std::vector> MSubM(std::vector>& a, std::vector>& b) +ModuleBase::matrix MSubM(ModuleBase::matrix& a, ModuleBase::matrix& b) { - assert(!a.empty() && !b.empty()); - assert(a.size() == b.size() && a[0].size() == b[0].size()); - std::vector> result = std::vector>(a.size(), std::vector(a[0].size(), 0.0)); - for(int i = 0; i < a.size(); i++) + assert(a.nr!=0 && a.nc!=0 && b.nr!=0 && b.nc!=0); + assert(a.nr == b.nr && a.nc == b.nc); + ModuleBase::matrix result = ModuleBase::matrix(a.nr, a.nc); + for(int i = 0; i < a.nr; i++) { - for(int j = 0; j < a[0].size(); j++) + for(int j = 0; j < a.nc; j++) { - result[i][j] = a[i][j] - b[i][j]; + result(i,j) = a(i,j) - b(i,j); } } return result; @@ -144,7 +144,6 @@ std::vector> MSubM(std::vector>& a, std: std::vector DotInVAndFloat(std::vector& vec, double b) { - assert(b != 0); std::vector result(vec.size(), 0.0); for(int i = 0; i < vec.size(); i++) { diff --git a/source/source_relax/matrix_methods.h b/source/source_relax/matrix_methods.h index fb6bba42b9..adb8f214b1 100644 --- a/source/source_relax/matrix_methods.h +++ b/source/source_relax/matrix_methods.h @@ -4,19 +4,20 @@ #include #include #include "source_base/vector3.h" +#include "source_base/matrix.h" std::vector ReshapeMToV(std::vector>& matrix); -std::vector> MAddM(std::vector>& a, std::vector>& b); +ModuleBase::matrix MAddM(ModuleBase::matrix& a, ModuleBase::matrix& b); std::vector VSubV(std::vector& a, std::vector& b); std::vector VAddV(std::vector& a, std::vector& b); std::vector> ReshapeVToM(std::vector& matrix); -std::vector DotInMAndV1(std::vector>& matrix, std::vector& vec); -std::vector DotInMAndV2(std::vector>& matrix, std::vector& vec); +std::vector DotInMAndV1(ModuleBase::matrix& matrix, std::vector& vec); +std::vector DotInMAndV2(ModuleBase::matrix& matrix, std::vector& vec); double DotInVAndV(std::vector& vec1, std::vector& vec2); -std::vector> OuterVAndV(std::vector& a, std::vector& b); -std::vector> MPlus(std::vector>& a, double b); -std::vector> MSubM(std::vector>& a, std::vector>& b); +ModuleBase::matrix OuterVAndV(std::vector& a, std::vector& b); +ModuleBase::matrix MPlus(ModuleBase::matrix& a, double b); +ModuleBase::matrix MSubM(ModuleBase::matrix& a, ModuleBase::matrix& b); std::vector DotInVAndFloat(std::vector& vec, double b); diff --git a/source/source_relax/test/CMakeLists.txt b/source/source_relax/test/CMakeLists.txt index 5f8a600cc6..f67b249965 100644 --- a/source/source_relax/test/CMakeLists.txt +++ b/source/source_relax/test/CMakeLists.txt @@ -38,7 +38,7 @@ AddTest( AddTest( TARGET lattice_change_basic_test LIBS parameter ${math_libs} base device - SOURCES lattice_change_basic_test.cpp ../lattice_change_basic.cpp + SOURCES lattice_change_basic_test.cpp ../lattice_change_basic.cpp ) AddTest( diff --git a/source/source_relax/test/bfgs_test.cpp b/source/source_relax/test/bfgs_test.cpp index fb82b90ca0..5a606974eb 100644 --- a/source/source_relax/test/bfgs_test.cpp +++ b/source/source_relax/test/bfgs_test.cpp @@ -38,7 +38,6 @@ TEST_F(BFGSTest, TestAllocate) bfgs.allocate(size); // Check if allocated arrays are not empty - EXPECT_FALSE(bfgs.H.empty()); EXPECT_FALSE(bfgs.pos.empty()); EXPECT_FALSE(bfgs.pos0.empty()); EXPECT_FALSE(bfgs.pos_taud.empty());