From ef9dd5ae1d04419d452b6358c958881c9f124d6e Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 8 Jun 2026 21:09:12 +0800 Subject: [PATCH 01/50] format update --- source/source_relax/bfgs.cpp | 2 +- source/source_relax/bfgs_basic.cpp | 2 +- source/source_relax/ions_move_bfgs.cpp | 16 ++-- source/source_relax/lattice_change_basic.cpp | 36 ++++---- source/source_relax/line_search.cpp | 14 ++-- source/source_relax/relax_driver.cpp | 84 +++++++++---------- source/source_relax/relax_driver.h | 6 +- source/source_relax/relax_nsync.cpp | 2 +- .../source_relax/test/ions_move_bfgs_test.cpp | 14 ++-- 9 files changed, 88 insertions(+), 88 deletions(-) diff --git a/source/source_relax/bfgs.cpp b/source/source_relax/bfgs.cpp index 13b87f55097..b7fbbe821a1 100644 --- a/source/source_relax/bfgs.cpp +++ b/source/source_relax/bfgs.cpp @@ -320,7 +320,7 @@ void BFGS::UpdatePos(UnitCell& ucell) move_ion[iat * 3 + 2] = move_ion_dr.z ; } } - ucell.update_pos_taud(move_ion); + ucell.update_pos_taud(move_ion); pos = this->MAddM(pos, dpos);*/ } diff --git a/source/source_relax/bfgs_basic.cpp b/source/source_relax/bfgs_basic.cpp index d598519fc3e..bdd7ae67626 100644 --- a/source/source_relax/bfgs_basic.cpp +++ b/source/source_relax/bfgs_basic.cpp @@ -76,7 +76,7 @@ void BFGS_Basic::update_inverse_hessian(const double &lat0) for (int i = 0; i < dim; i++) { // s[i] = this->pos[i] - this->pos_p[i]; - // mohan update 2010-07-27 + // mohan update 2010-07-27 s[i] = this->check_move(lat0, pos[i], pos_p[i]); s[i] *= lat0; diff --git a/source/source_relax/ions_move_bfgs.cpp b/source/source_relax/ions_move_bfgs.cpp index ee8a9d97e98..d3ff58732ca 100644 --- a/source/source_relax/ions_move_bfgs.cpp +++ b/source/source_relax/ions_move_bfgs.cpp @@ -23,10 +23,10 @@ Ions_Move_BFGS::~Ions_Move_BFGS(){}; void Ions_Move_BFGS::allocate() { ModuleBase::TITLE("Ions_Move_BFGS", "init"); - if (init_done) - { - return; - } + if (init_done) + { + return; + } this->allocate_basic(); // initialize data members @@ -50,9 +50,9 @@ void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con Ions_Move_Basic::setup_gradient(ucell, force, this->pos, this->grad); first_step = false; } - else - { - std::vector pos_tmp(3 * ucell.nat); + else + { + std::vector pos_tmp(3 * ucell.nat); Ions_Move_Basic::setup_gradient(ucell, force, pos_tmp.data(), this->grad); } // use energy_in and istep to setup etot and etot_old. @@ -129,7 +129,7 @@ void Ions_Move_BFGS::restart_bfgs(const double& lat0) } else { - // bfgs initialization + // bfgs initialization ModuleBase::GlobalFunc::ZEROS(pos_p, dim); ModuleBase::GlobalFunc::ZEROS(grad_p, dim); ModuleBase::GlobalFunc::ZEROS(move_p, dim); diff --git a/source/source_relax/lattice_change_basic.cpp b/source/source_relax/lattice_change_basic.cpp index 47b0c283e19..1bc41ce6238 100644 --- a/source/source_relax/lattice_change_basic.cpp +++ b/source/source_relax/lattice_change_basic.cpp @@ -117,24 +117,24 @@ void Lattice_Change_Basic::change_lattice(UnitCell &ucell, double *move, double if (ModuleSymmetry::Symmetry::symm_flag && ucell.symm.nrotk > 0) { ModuleBase::matrix move_mat_t(3, 3); - for (int i = 0;i < 3;++i) - { - for (int j = 0;j < 3;++j) - { - move_mat_t(j, i) = move[i * 3 + j] / ucell.lat0; //transpose - } - } - ModuleBase::matrix symm_move_mat_t = (move_mat_t * ucell.G.to_matrix());//symmetrize (latvec^{-1} * move_mat)^T + for (int i = 0;i < 3;++i) + { + for (int j = 0;j < 3;++j) + { + move_mat_t(j, i) = move[i * 3 + j] / ucell.lat0; //transpose + } + } + ModuleBase::matrix symm_move_mat_t = (move_mat_t * ucell.G.to_matrix());//symmetrize (latvec^{-1} * move_mat)^T ucell.symm.symmetrize_mat3(symm_move_mat_t, ucell.lat); move_mat_t = symm_move_mat_t * ucell.latvec.Transpose().to_matrix();//G^{-1}=latvec^T - for (int i = 0;i < 3;++i) - { - for (int j = 0;j < 3;++j) - { - move[i * 3 + j] = move_mat_t(j, i) * ucell.lat0;//transpose back - } - } + for (int i = 0;i < 3;++i) + { + for (int j = 0;j < 3;++j) + { + move[i * 3 + j] = move_mat_t(j, i) * ucell.lat0;//transpose back + } + } } if (ucell.lc[0] != 0) @@ -252,9 +252,9 @@ void Lattice_Change_Basic::check_converged(const UnitCell &ucell, ModuleBase::ma for (int i = 0; i < 3; i++) { if (stress_ii_max < std::abs(stress(i, i))) - { - stress_ii_max = std::abs(stress(i, i)); - } + { + stress_ii_max = std::abs(stress(i, i)); + } for (int j = 0; j < 3; j++) { if (Lattice_Change_Basic::largest_grad < std::abs(stress(i, j))) diff --git a/source/source_relax/line_search.cpp b/source/source_relax/line_search.cpp index 1c07a59c3d4..813fa002cb9 100644 --- a/source/source_relax/line_search.cpp +++ b/source/source_relax/line_search.cpp @@ -15,7 +15,7 @@ bool Line_Search::line_search(const bool restart, { if (restart) { - ls_step = 0; + ls_step = 0; } if (ls_step == 0) // first point: make a trial step into trial direction @@ -103,7 +103,7 @@ bool Line_Search::third_order(const double x, const double y, const double f, do dmoveh = -fa / (fab - fa) / 2.0; if (dmoveh < 0) - { + { dmoveh = 4.0; } @@ -116,7 +116,7 @@ bool Line_Search::third_order(const double x, const double y, const double f, do if (dmove > 4.0) { - dmove = 4.0; + dmove = 4.0; } xnew = dmove + xa; @@ -143,7 +143,7 @@ void Line_Search::init_brent(const double x, const double y, const double f) yb = y; fb = f; if (fa * fb > 0) - { + { bracked = false; } fstart = fa; @@ -240,7 +240,7 @@ bool Line_Search::brent(const double x, const double y, const double f, double& qq = (qq - 1.0) * (r - 1.0) * (s - 1.0); } if (p > 0.0) - { + { qq = -qq; } p = std::abs(p); @@ -281,7 +281,7 @@ bool Line_Search::brent(const double x, const double y, const double f, double& xnew = xb; if (std::abs(dy) < conv_thr) - { + { return true; } if (ls_step == 4) // I'm not sure if this is a good choice, but the idea is there should not be so many line @@ -344,7 +344,7 @@ bool Line_Search::brent(const double x, const double y, const double f, double& qq = (qq - 1.0) * (r - 1.0) * (s - 1.0); } if (p > 0.0) - { + { qq = -qq; } p = std::abs(p); diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index ef97baf4dd7..82d96b7b9dd 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -10,9 +10,9 @@ #include "source_cell/print_cell.h" void Relax_Driver::relax_driver( - ModuleESolver::ESolver* p_esolver, - UnitCell& ucell, - const Input_para& inp) + ModuleESolver::ESolver* p_esolver, + UnitCell& ucell, + const Input_para& inp) { ModuleBase::TITLE("Relax_Driver", "relax_driver"); ModuleBase::timer::start("Relax_Driver", "relax_driver"); @@ -38,13 +38,13 @@ void Relax_Driver::relax_driver( { time_t estart = time(nullptr); - if (inp.out_level == "ie" - && (inp.calculation == "relax" - || inp.calculation == "cell-relax" - || inp.calculation == "scf" - || inp.calculation == "nscf") - && (inp.esolver_type != "lr")) - { + if (inp.out_level == "ie" + && (inp.calculation == "relax" + || inp.calculation == "cell-relax" + || inp.calculation == "scf" + || inp.calculation == "nscf") + && (inp.esolver_type != "lr")) + { ModuleIO::print_screen(stress_step, force_step, istep); } @@ -73,10 +73,10 @@ void Relax_Driver::relax_driver( { p_esolver->cal_force(ucell, force); } - else - { + else + { // do nothing - } + } // calculate and gather all parts of stress @@ -84,10 +84,10 @@ void Relax_Driver::relax_driver( { p_esolver->cal_stress(ucell, stress); } - else - { + else + { // do nothing - } + } if (inp.calculation == "relax" || inp.calculation == "cell-relax") { @@ -181,37 +181,37 @@ void Relax_Driver::relax_driver( "data_?"); } - if (inp.calculation == "relax" || inp.calculation == "cell-relax") - { - if (istep-1 == inp.relax_nmax) - { - std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; - std::cout << " Geometry relaxation stops here due to reaching the maximum " << std::endl; - std::cout << " relaxation steps. More steps are needed to converge the results " << std::endl; - std::cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; - } - else - { - std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; - std::cout << " Geometry relaxation thresholds are reached within " << istep-1 << " steps." << std::endl; - std::cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; - } - } - else - { - // do nothing - } - - if (inp.relax_nmax == 0) + if (inp.calculation == "relax" || inp.calculation == "cell-relax") + { + if (istep-1 == inp.relax_nmax) + { + std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; + std::cout << " Geometry relaxation stops here due to reaching the maximum " << std::endl; + std::cout << " relaxation steps. More steps are needed to converge the results " << std::endl; + std::cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; + } + else + { + std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; + std::cout << " Geometry relaxation thresholds are reached within " << istep-1 << " steps." << std::endl; + std::cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; + } + } + else + { + // do nothing + } + + if (inp.relax_nmax == 0) { std::cout << "-----------------------------------------------" << std::endl; std::cout << " relax_nmax = 0, DRY RUN TEST SUCCEEDS :)" << std::endl; std::cout << "-----------------------------------------------" << std::endl; } - else - { - // do nothing - } + else + { + // do nothing + } ModuleBase::timer::end("Relax_Driver", "relax_driver"); return; diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index 8063205caaf..78b343efd81 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -16,9 +16,9 @@ class Relax_Driver Relax_Driver(){}; ~Relax_Driver(){}; - void relax_driver(ModuleESolver::ESolver* p_esolver, - UnitCell& ucell, - const Input_para& inp); + void relax_driver(ModuleESolver::ESolver* p_esolver, + UnitCell& ucell, + const Input_para& inp); private: // mohan add 2021-01-28 diff --git a/source/source_relax/relax_nsync.cpp b/source/source_relax/relax_nsync.cpp index d50a07ded03..9541c9dc177 100644 --- a/source/source_relax/relax_nsync.cpp +++ b/source/source_relax/relax_nsync.cpp @@ -89,7 +89,7 @@ bool Relax_old::if_do_relax(const UnitCell& ucell) ModuleBase::WARNING("Ions", "No atom is allowed to move!"); return false; } - // if(!IMM.get_converged()) return 1; + // if(!IMM.get_converged()) return 1; else { assert(PARAM.inp.cal_force == 1); diff --git a/source/source_relax/test/ions_move_bfgs_test.cpp b/source/source_relax/test/ions_move_bfgs_test.cpp index a9094e20212..bbf9bfadf93 100644 --- a/source/source_relax/test/ions_move_bfgs_test.cpp +++ b/source/source_relax/test/ions_move_bfgs_test.cpp @@ -187,13 +187,13 @@ TEST_F(IonsMoveBFGSTest, RestartBfgsCase2) for (int j = 0; j < Ions_Move_Basic::dim; ++j) { if (i == j) - { - EXPECT_DOUBLE_EQ(bfgs.inv_hess(i, j), 1.0); - } - else - { - EXPECT_DOUBLE_EQ(bfgs.inv_hess(i, j), 0.0); - } + { + EXPECT_DOUBLE_EQ(bfgs.inv_hess(i, j), 1.0); + } + else + { + EXPECT_DOUBLE_EQ(bfgs.inv_hess(i, j), 0.0); + } } } } From cfdf83f5b50722e0b2329fa60f6dcb629d808461 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 8 Jun 2026 21:17:47 +0800 Subject: [PATCH 02/50] replace new with vector --- source/source_relax/ions_move_sd.cpp | 28 ++++++++-------------------- source/source_relax/ions_move_sd.h | 8 +++++--- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/source/source_relax/ions_move_sd.cpp b/source/source_relax/ions_move_sd.cpp index e3831623050..133f809367c 100644 --- a/source/source_relax/ions_move_sd.cpp +++ b/source/source_relax/ions_move_sd.cpp @@ -4,32 +4,19 @@ #include "ions_move_basic.h" #include "source_base/global_function.h" #include "source_base/global_variable.h" -#include using namespace Ions_Move_Basic; -Ions_Move_SD::Ions_Move_SD() +Ions_Move_SD::Ions_Move_SD() : energy_saved(1.0e10) { - this->energy_saved = 1.0e10; - this->grad_saved = nullptr; - this->pos_saved = nullptr; -} -Ions_Move_SD::~Ions_Move_SD() -{ - delete[] grad_saved; - delete[] pos_saved; } void Ions_Move_SD::allocate() { ModuleBase::TITLE("Ions_Move_SD", "allocate"); assert(dim > 0); - delete[] grad_saved; - delete[] pos_saved; - this->grad_saved = new double[dim]; - this->pos_saved = new double[dim]; - ModuleBase::GlobalFunc::ZEROS(grad_saved, dim); - ModuleBase::GlobalFunc::ZEROS(pos_saved, dim); + grad_saved.resize(dim, 0.0); + pos_saved.resize(dim, 0.0); } void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot_in) @@ -37,8 +24,8 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const ModuleBase::TITLE("Ions_Move_SD", "start"); assert(dim > 0); - assert(grad_saved != nullptr); - assert(pos_saved != nullptr); + assert(grad_saved.size() == static_cast(dim)); + assert(pos_saved.size() == static_cast(dim)); std::vector pos(dim); std::vector grad(dim); @@ -58,9 +45,10 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const printf("in cheak_converged"); printf("pos[0]: %f\n", pos[0]); energy_saved = etot_in; - for (int i = 0; i < dim; i++) { + for (int i = 0; i < dim; i++) + { pos_saved[i] = pos[i]; -} + } for (int i = 0; i < dim; i++) { grad_saved[i] = grad[i]; diff --git a/source/source_relax/ions_move_sd.h b/source/source_relax/ions_move_sd.h index 0fa56f8696a..e2eb53d587c 100644 --- a/source/source_relax/ions_move_sd.h +++ b/source/source_relax/ions_move_sd.h @@ -3,19 +3,21 @@ #include "source_base/matrix.h" #include "source_cell/unitcell.h" +#include + class Ions_Move_SD { public: Ions_Move_SD(); - ~Ions_Move_SD(); + ~Ions_Move_SD() = default; void allocate(void); void start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot); private: double energy_saved; - double* pos_saved = nullptr; - double* grad_saved = nullptr; + std::vector pos_saved; + std::vector grad_saved; void cal_tradius_sd(void) const; }; From 94eb11bb4a66cd2c85ff9cb009984f18ab2327f5 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 8 Jun 2026 21:24:16 +0800 Subject: [PATCH 03/50] format update --- source/source_relax/line_search.cpp | 32 ++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source/source_relax/line_search.cpp b/source/source_relax/line_search.cpp index 813fa002cb9..db5a049382b 100644 --- a/source/source_relax/line_search.cpp +++ b/source/source_relax/line_search.cpp @@ -13,9 +13,9 @@ bool Line_Search::line_search(const bool restart, double& xnew, // the next point that we want to try const double conv_thr) { - if (restart) + if (restart) { - ls_step = 0; + ls_step = 0; } if (ls_step == 0) // first point: make a trial step into trial direction @@ -102,8 +102,8 @@ bool Line_Search::third_order(const double x, const double y, const double f, do } dmoveh = -fa / (fab - fa) / 2.0; - if (dmoveh < 0) - { + if (dmoveh < 0) + { dmoveh = 4.0; } @@ -114,14 +114,14 @@ bool Line_Search::third_order(const double x, const double y, const double f, do } } // end anharmonic case - if (dmove > 4.0) + if (dmove > 4.0) { - dmove = 4.0; + dmove = 4.0; } xnew = dmove + xa; double dy = (fb + (fab - fb) / (xa - xb) * (dmove - xb)) * (dmove - xb); - if (std::abs(dy) < conv_thr) + if (std::abs(dy) < conv_thr) { return true; } @@ -142,8 +142,8 @@ void Line_Search::init_brent(const double x, const double y, const double f) xb = x; yb = y; fb = f; - if (fa * fb > 0) - { + if (fa * fb > 0) + { bracked = false; } fstart = fa; @@ -239,8 +239,8 @@ bool Line_Search::brent(const double x, const double y, const double f, double& p = s * (2.0 * xm * qq * (qq - r) - (xb - xa) * (r - 1.0)); qq = (qq - 1.0) * (r - 1.0) * (s - 1.0); } - if (p > 0.0) - { + if (p > 0.0) + { qq = -qq; } p = std::abs(p); @@ -280,8 +280,8 @@ bool Line_Search::brent(const double x, const double y, const double f, double& } xnew = xb; - if (std::abs(dy) < conv_thr) - { + if (std::abs(dy) < conv_thr) + { return true; } if (ls_step == 4) // I'm not sure if this is a good choice, but the idea is there should not be so many line @@ -343,8 +343,8 @@ bool Line_Search::brent(const double x, const double y, const double f, double& p = s * (2.0 * xm * qq * (qq - r) - (xb - xa) * (r - 1.0)); qq = (qq - 1.0) * (r - 1.0) * (s - 1.0); } - if (p > 0.0) - { + if (p > 0.0) + { qq = -qq; } p = std::abs(p); @@ -390,7 +390,7 @@ bool Line_Search::brent(const double x, const double y, const double f, double& } xnew = xb; - if (std::abs(dy) < conv_thr) + if (std::abs(dy) < conv_thr) { return true; } From 6fcf5cf5900b6aeb5d9dbf057f8cdbe14f1c4849 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 8 Jun 2026 21:27:46 +0800 Subject: [PATCH 04/50] update --- source/source_relax/bfgs_basic.cpp | 56 +++++++----------------------- source/source_relax/bfgs_basic.h | 15 ++++---- 2 files changed, 20 insertions(+), 51 deletions(-) diff --git a/source/source_relax/bfgs_basic.cpp b/source/source_relax/bfgs_basic.cpp index bdd7ae67626..f542d209a30 100644 --- a/source/source_relax/bfgs_basic.cpp +++ b/source/source_relax/bfgs_basic.cpp @@ -1,10 +1,9 @@ #include "bfgs_basic.h" - #include "source_io/module_parameter/parameter.h" #include "ions_move_basic.h" #include "source_base/global_function.h" #include "source_base/global_variable.h" -#include + using namespace Ions_Move_Basic; double BFGS_Basic::relax_bfgs_w1 = -1.0; // default is 0.01 @@ -12,50 +11,19 @@ double BFGS_Basic::relax_bfgs_w2 = -1.0; // defalut is 0.05 BFGS_Basic::BFGS_Basic() { - pos = nullptr; - pos_p = nullptr; - grad = nullptr; - grad_p = nullptr; - move = nullptr; - move_p = nullptr; - bfgs_ndim = 1; } -BFGS_Basic::~BFGS_Basic() -{ - delete[] pos; - delete[] pos_p; - delete[] grad; - delete[] grad_p; - delete[] move; - delete[] move_p; -} - void BFGS_Basic::allocate_basic(void) { assert(dim > 0); - delete[] pos; - delete[] pos_p; - delete[] grad; - delete[] grad_p; - delete[] move; - delete[] move_p; - - pos = new double[dim]; - pos_p = new double[dim]; - grad = new double[dim]; - grad_p = new double[dim]; - move = new double[dim]; - move_p = new double[dim]; - - ModuleBase::GlobalFunc::ZEROS(pos, dim); - ModuleBase::GlobalFunc::ZEROS(grad, dim); - ModuleBase::GlobalFunc::ZEROS(pos_p, dim); - ModuleBase::GlobalFunc::ZEROS(grad_p, dim); - ModuleBase::GlobalFunc::ZEROS(move, dim); - ModuleBase::GlobalFunc::ZEROS(move_p, dim); + pos.resize(dim, 0.0); + pos_p.resize(dim, 0.0); + grad.resize(dim, 0.0); + grad_p.resize(dim, 0.0); + move.resize(dim, 0.0); + move_p.resize(dim, 0.0); // init inverse Hessien matrix. inv_hess.create(dim, dim); @@ -134,8 +102,8 @@ void BFGS_Basic::update_inverse_hessian(const double &lat0) void BFGS_Basic::check_wolfe_conditions(void) { - double dot_p = dot_func(grad_p, move_p, dim); - double dot = dot_func(grad, move_p, dim); + double dot_p = dot_func(grad_p.data(), move_p.data(), dim); + double dot = dot_func(grad.data(), move_p.data(), dim); // if the total energy falls rapidly, enlarge the trust radius. bool wolfe1 = (etot - etot_p) < this->relax_bfgs_w1 * dot_p; @@ -263,7 +231,7 @@ void BFGS_Basic::new_step(const double &lat0) // std::cout << " move after hess " << move[i] << std::endl; } - GlobalV::ofs_running << " check the norm of new move " << dot_func(move, move, dim) << " (Bohr)" << std::endl; + GlobalV::ofs_running << " check the norm of new move " << dot_func(move.data(), move.data(), dim) << " (Bohr)" << std::endl; } else if (bfgs_ndim > 1) { @@ -313,13 +281,13 @@ void BFGS_Basic::compute_trust_radius(void) ModuleBase::TITLE("BFGS_Basic", "compute_trust_radius"); // (1) judge 1 - double dot = dot_func(grad_p, move_p, dim); + double dot = dot_func(grad_p.data(), move_p.data(), dim); bool ltest = (etot - etot_p) < this->relax_bfgs_w1 * dot; // (2) judge 2 // calculate the norm of move, which // is used to compare to trust_radius_old. - double norm_move = dot_func(this->move, this->move, dim); + double norm_move = dot_func(this->move.data(), this->move.data(), dim); norm_move = std::sqrt(norm_move); ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "move(norm)", norm_move); diff --git a/source/source_relax/bfgs_basic.h b/source/source_relax/bfgs_basic.h index 85de10474ac..6e74cac9cdd 100644 --- a/source/source_relax/bfgs_basic.h +++ b/source/source_relax/bfgs_basic.h @@ -2,6 +2,7 @@ #define BFGS_BASIC #include "source_base/matrix.h" +#include // references // 1) Roger Fletcher, Practical Methods of Optimization, John Wiley and @@ -18,7 +19,7 @@ class BFGS_Basic public: BFGS_Basic(); - ~BFGS_Basic(); + ~BFGS_Basic() = default; protected: void allocate_basic(void); @@ -26,13 +27,13 @@ class BFGS_Basic void reset_hessian(void); void save_bfgs(void); - double* pos = nullptr; // std::vector containing 3N coordinates of the system ( x ) - double* grad = nullptr; // std::vector containing 3N components of ( grad( V(x) ) ) - double* move = nullptr; // pos = pos_p + move. + std::vector pos; // std::vector containing 3N coordinates of the system ( x ) + std::vector grad; // std::vector containing 3N components of ( grad( V(x) ) ) + std::vector move; // pos = pos_p + move. - double* pos_p = nullptr; // p: previous - double* grad_p = nullptr; // p: previous - double* move_p = nullptr; + std::vector pos_p; // p: previous + std::vector grad_p; // p: previous + std::vector move_p; public: // mohan update 2011-06-12 static double relax_bfgs_w1; // fixed: parameters for Wolfe conditions. From 01621e99051e4cf7bfc786e1b97c08f0ba095535 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 8 Jun 2026 21:29:41 +0800 Subject: [PATCH 05/50] update --- source/source_relax/ions_move_bfgs.cpp | 16 +++--- source/source_relax/lattice_change_cg.cpp | 63 ++++++++--------------- source/source_relax/lattice_change_cg.h | 11 ++-- 3 files changed, 35 insertions(+), 55 deletions(-) diff --git a/source/source_relax/ions_move_bfgs.cpp b/source/source_relax/ions_move_bfgs.cpp index d3ff58732ca..31c9f33f86d 100644 --- a/source/source_relax/ions_move_bfgs.cpp +++ b/source/source_relax/ions_move_bfgs.cpp @@ -47,19 +47,19 @@ void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con // In the following steps, the pos is updated by BFGS methods. if (first_step) { - Ions_Move_Basic::setup_gradient(ucell, force, this->pos, this->grad); + Ions_Move_Basic::setup_gradient(ucell, force, this->pos.data(), this->grad.data()); first_step = false; } else { std::vector pos_tmp(3 * ucell.nat); - Ions_Move_Basic::setup_gradient(ucell, force, pos_tmp.data(), this->grad); + Ions_Move_Basic::setup_gradient(ucell, force, pos_tmp.data(), this->grad.data()); } // use energy_in and istep to setup etot and etot_old. Ions_Move_Basic::setup_etot(energy_in, false); // use gradient and etot and etot_old to check // if the result is converged. - Ions_Move_Basic::check_converged(ucell, this->grad); + Ions_Move_Basic::check_converged(ucell, this->grad.data()); if (Ions_Move_Basic::converged) { @@ -86,7 +86,7 @@ void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con // even if the energy is higher, we save the information. this->save_bfgs(); - Ions_Move_Basic::move_atoms(ucell, move, pos); + Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data()); } return; } @@ -130,9 +130,9 @@ void Ions_Move_BFGS::restart_bfgs(const double& lat0) else { // bfgs initialization - ModuleBase::GlobalFunc::ZEROS(pos_p, dim); - ModuleBase::GlobalFunc::ZEROS(grad_p, dim); - ModuleBase::GlobalFunc::ZEROS(move_p, dim); + ModuleBase::GlobalFunc::ZEROS(pos_p.data(), dim); + ModuleBase::GlobalFunc::ZEROS(grad_p.data(), dim); + ModuleBase::GlobalFunc::ZEROS(move_p.data(), dim); Ions_Move_Basic::update_iter = 0; @@ -304,7 +304,7 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0) ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "update iteration", Ions_Move_Basic::update_iter); // combine the direction and move length now - double norm = dot_func(this->move, this->move, dim); + double norm = dot_func(this->move.data(), this->move.data(), dim); norm = sqrt(norm); if (norm < 1.0e-16) diff --git a/source/source_relax/lattice_change_cg.cpp b/source/source_relax/lattice_change_cg.cpp index 1ed2449c26a..d0172ba7845 100644 --- a/source/source_relax/lattice_change_cg.cpp +++ b/source/source_relax/lattice_change_cg.cpp @@ -24,18 +24,7 @@ using namespace Lattice_Change_Basic; Lattice_Change_CG::Lattice_Change_CG() { - this->lat0 = nullptr; - this->grad0 = nullptr; - this->cg_grad0 = nullptr; - this->move0 = nullptr; -} - -Lattice_Change_CG::~Lattice_Change_CG() -{ - delete[] lat0; - delete[] grad0; - delete[] cg_grad0; - delete[] move0; + this->e0 = 0.0; } void Lattice_Change_CG::allocate(void) @@ -44,20 +33,10 @@ void Lattice_Change_CG::allocate(void) // mohan add 2021-02-07 assert(dim > 0); - delete[] lat0; - delete[] grad0; - delete[] cg_grad0; - delete[] move0; - - this->lat0 = new double[dim]; - this->grad0 = new double[dim]; - this->cg_grad0 = new double[dim]; - this->move0 = new double[dim]; - - ModuleBase::GlobalFunc::ZEROS(lat0, dim); - ModuleBase::GlobalFunc::ZEROS(grad0, dim); - ModuleBase::GlobalFunc::ZEROS(cg_grad0, dim); - ModuleBase::GlobalFunc::ZEROS(move0, dim); + this->lat0.resize(dim, 0.0); + this->grad0.resize(dim, 0.0); + this->cg_grad0.resize(dim, 0.0); + this->move0.resize(dim, 0.0); this->e0 = 0.0; } @@ -65,10 +44,10 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ { ModuleBase::TITLE("Lattice_Change_CG", "start"); - assert(lat0 != 0); - assert(grad0 != 0); - assert(cg_grad0 != 0); - assert(move0 != 0); + assert(lat0.size() == static_cast(dim)); + assert(grad0.size() == static_cast(dim)); + assert(cg_grad0.size() == static_cast(dim)); + assert(move0.size() == static_cast(dim)); // sd , trial are two parameters, when sd=trial=true, @@ -158,16 +137,16 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ { e0 = etot_in; setup_cg_grad(grad, - grad0, + grad0.data(), cg_grad, - cg_grad0, + cg_grad0.data(), ncggrad, flag); // we use the last direction ,the last grad and the grad now to get the direction now ncggrad++; normalize(cg_gradn, cg_grad, dim); - setup_move(move0, cg_gradn, steplength); // move the atom position - Lattice_Change_Basic::change_lattice(ucell, move0, lat); + setup_move(move0.data(), cg_gradn, steplength); // move the atom position + Lattice_Change_Basic::change_lattice(ucell, move0.data(), lat); for (int i = 0; i < dim; i++) // grad0 ,cg_grad0 are used to store the grad and cg_grad for the future using { @@ -175,8 +154,8 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ cg_grad0[i] = cg_grad[i]; } - f_cal(move0, move0, dim, xb); // xb = trial steplength - f_cal(move0, grad, dim, fa); // fa is the projection force in this direction + f_cal(move0.data(), move0.data(), dim, xb); // xb = trial steplength + f_cal(move0.data(), grad, dim, fa); // fa is the projection force in this direction fmax = fa; sd = false; @@ -188,8 +167,8 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ if (trial) { double e1 = etot_in; - f_cal(move0, grad, dim, fb); - f_cal(move0, move0, dim, xb); + f_cal(move0.data(), grad, dim, fb); + f_cal(move0.data(), move0.data(), dim, xb); if ((std::abs(fb) < std::abs((fa) / 10.0))) { @@ -200,7 +179,7 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ goto CG_begin; } - normalize(cg_gradn, cg_grad0, dim); + normalize(cg_gradn, cg_grad0.data(), dim); third_order(e0, e1, fa, fb, xb, best_x); // cubic interpolation if (best_x > 6 * xb || best_x < (-xb)) @@ -213,7 +192,7 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ trial = false; xa = 0; - f_cal(move0, move, dim, xc); + f_cal(move0.data(), move, dim, xc); xc = xb + xc; xpt = xc; @@ -222,7 +201,7 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ else { double xtemp, ftemp; - f_cal(move0, grad, dim, fc); + f_cal(move0.data(), grad, dim, fc); fmin = std::abs(fc); nbrent++; @@ -251,7 +230,7 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ goto CG_begin; } - normalize(cg_gradn, cg_grad0, dim); + normalize(cg_gradn, cg_grad0.data(), dim); setup_move(move, cg_gradn, best_x); Lattice_Change_Basic::change_lattice(ucell, move, lat); diff --git a/source/source_relax/lattice_change_cg.h b/source/source_relax/lattice_change_cg.h index 68fe1b69509..76d8dc70f8d 100644 --- a/source/source_relax/lattice_change_cg.h +++ b/source/source_relax/lattice_change_cg.h @@ -3,21 +3,22 @@ #include "source_base/matrix.h" #include "source_cell/unitcell.h" +#include class Lattice_Change_CG { public: Lattice_Change_CG(); - ~Lattice_Change_CG(); + ~Lattice_Change_CG() = default; void allocate(void); void start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot); private: - double * lat0 = nullptr; - double * grad0 = nullptr; - double * cg_grad0 = nullptr; - double * move0 = nullptr; + std::vector lat0; + std::vector grad0; + std::vector cg_grad0; + std::vector move0; double e0=0.0; // setup gradients. From 1b8d93897500f7f420df4445b1e723b2476b705a Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 8 Jun 2026 21:36:13 +0800 Subject: [PATCH 06/50] update --- source/source_relax/CMakeLists.txt | 3 -- source/source_relax/ions_move_basic.cpp | 6 ++- source/source_relax/ions_move_basic.h | 50 +++++++++---------------- source/source_relax/ions_move_sd.cpp | 4 +- 4 files changed, 24 insertions(+), 39 deletions(-) diff --git a/source/source_relax/CMakeLists.txt b/source/source_relax/CMakeLists.txt index 30415edd3b5..136523a620f 100644 --- a/source/source_relax/CMakeLists.txt +++ b/source/source_relax/CMakeLists.txt @@ -1,12 +1,9 @@ add_library( relax OBJECT - relax_driver.cpp - relax_sync.cpp line_search.cpp - bfgs.cpp lbfgs.cpp relax_nsync.cpp diff --git a/source/source_relax/ions_move_basic.cpp b/source/source_relax/ions_move_basic.cpp index e4a2caef9db..5eea695ceaf 100644 --- a/source/source_relax/ions_move_basic.cpp +++ b/source/source_relax/ions_move_basic.cpp @@ -5,6 +5,7 @@ #include "source_base/global_variable.h" #include "source_cell/update_cell.h" #include "source_cell/print_cell.h" + int Ions_Move_Basic::dim = 0; bool Ions_Move_Basic::converged = false; double Ions_Move_Basic::largest_grad = 0.0; @@ -96,9 +97,10 @@ void Ions_Move_Basic::move_atoms(UnitCell &ucell, double *move, double *pos) const double move_threshold = 1.0e-10; const int total_freedom = ucell.nat * 3; - if (ModuleSymmetry::Symmetry::symm_flag && ucell.symm.all_mbl && ucell.symm.nrotk > 0) { + if (ModuleSymmetry::Symmetry::symm_flag && ucell.symm.all_mbl && ucell.symm.nrotk > 0) + { ucell.symm.symmetrize_vec3_nat(move); -} + } for (int i = 0; i < total_freedom; i++) { diff --git a/source/source_relax/ions_move_basic.h b/source/source_relax/ions_move_basic.h index 8f030850286..e26acbba2fa 100644 --- a/source/source_relax/ions_move_basic.h +++ b/source/source_relax/ions_move_basic.h @@ -6,56 +6,42 @@ namespace Ions_Move_Basic { -extern int dim; // dimension of the free variables, -extern bool converged; // converged force or not, -extern double largest_grad; // largest gradient among the forces, -extern int update_iter; // number of sucesfully updated iterations, -extern int istep; // index of ionic steps, -extern double ediff; // energy difference compared to last step, -extern double etot; // total energy of this step, -extern double etot_p; // total energy of last step, - -extern double trust_radius; // trust radius now, -extern double trust_radius_old; // old trust radius, -extern double relax_bfgs_rmax; // max value of trust radius, -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 int dim; // dimension of the free variables +extern bool converged; // converged force or not +extern double largest_grad; // largest gradient among the forces +extern int update_iter; // number of successfully updated iterations +extern int istep; // index of ionic steps +extern double ediff; // energy difference compared to last step +extern double etot; // total energy of this step +extern double etot_p; // total energy of last step + +extern double trust_radius; // trust radius now +extern double trust_radius_old; // old trust radius +extern double relax_bfgs_rmax; // max value of trust radius +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 initial step length +extern std::vector relax_method; // relaxation method extern int out_stru; // output the structure or not -// funny way to pass this parameter, but nevertheless -//---------------------------------------------------------------------------- // setup the gradient, all the same for any geometry optimization methods. -//---------------------------------------------------------------------------- void setup_gradient(const UnitCell &ucell, const ModuleBase::matrix &force, double *pos, double *grad); -//---------------------------------------------------------------------------- // move the atom positions, considering the periodic boundary condition. -//---------------------------------------------------------------------------- void move_atoms(UnitCell &ucell, double *move, double *pos); -//---------------------------------------------------------------------------- -// check the converged conditions ( if largest gradient is smaller than -// the threshold) -//---------------------------------------------------------------------------- +// check the converged conditions ( if largest gradient is smaller than the threshold ) void check_converged(const UnitCell &ucell, const double *grad); -//---------------------------------------------------------------------------- // terminate the geometry optimization. -//---------------------------------------------------------------------------- void terminate(const UnitCell &ucell); -//---------------------------------------------------------------------------- // setup the total energy, keep the new energy or not. -//---------------------------------------------------------------------------- void setup_etot(const double &energy_in, const bool judgement); double dot_func(const double *a, const double *b, const int &dim); -//---------------------------------------------------------------------------- -// third order interpolation scheme, -//---------------------------------------------------------------------------- +// third order interpolation scheme void third_order(); } // namespace Ions_Move_Basic diff --git a/source/source_relax/ions_move_sd.cpp b/source/source_relax/ions_move_sd.cpp index 133f809367c..8302e509a46 100644 --- a/source/source_relax/ions_move_sd.cpp +++ b/source/source_relax/ions_move_sd.cpp @@ -55,7 +55,7 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const } // normalize the gradient, in convinience to // move atom. - double norm = dot_func(grad_saved, grad_saved, dim); + double norm = dot_func(grad_saved.data(), grad_saved.data(), dim); norm = sqrt(norm); for (int i = 0; i < dim; i++) { @@ -75,7 +75,7 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const { move[i] = -grad_saved[i] * trust_radius; } - move_atoms(ucell, move.data(), pos_saved); + move_atoms(ucell, move.data(), pos_saved.data()); Ions_Move_Basic::update_iter++; } From 2730b795462782c03bdc4c10f86dd5f616010a4d Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 8 Jun 2026 21:53:57 +0800 Subject: [PATCH 07/50] move bfgs.h to ions_move_bfgs2.h --- source/Makefile.Objects | 2 +- source/source_relax/CMakeLists.txt | 2 +- .../{bfgs.cpp => ions_move_bfgs2.cpp} | 22 +++++++++---------- .../{bfgs.h => ions_move_bfgs2.h} | 8 +++---- source/source_relax/ions_move_methods.cpp | 2 +- source/source_relax/ions_move_methods.h | 4 ++-- source/source_relax/relax_driver.h | 4 ++-- source/source_relax/test/bfgs_test.cpp | 6 ++--- 8 files changed, 25 insertions(+), 25 deletions(-) rename source/source_relax/{bfgs.cpp => ions_move_bfgs2.cpp} (94%) rename source/source_relax/{bfgs.h => ions_move_bfgs2.h} (95%) diff --git a/source/Makefile.Objects b/source/Makefile.Objects index 6e1adc3f448..e1d14749d8c 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -464,6 +464,7 @@ OBJS_RELAXATION=bfgs_basic.o\ relax_driver.o\ ions_move_basic.o\ ions_move_bfgs.o\ + ions_move_bfgs2.o\ ions_move_cg.o\ ions_move_methods.o\ ions_move_sd.o\ @@ -472,7 +473,6 @@ OBJS_RELAXATION=bfgs_basic.o\ lattice_change_methods.o\ relax_nsync.o\ relax_sync.o\ - bfgs.o\ lbfgs.o\ matrix_methods.o\ line_search.o\ diff --git a/source/source_relax/CMakeLists.txt b/source/source_relax/CMakeLists.txt index 136523a620f..87aa8d1c3b3 100644 --- a/source/source_relax/CMakeLists.txt +++ b/source/source_relax/CMakeLists.txt @@ -4,12 +4,12 @@ add_library( relax_driver.cpp relax_sync.cpp line_search.cpp - bfgs.cpp lbfgs.cpp relax_nsync.cpp bfgs_basic.cpp ions_move_basic.cpp ions_move_bfgs.cpp + ions_move_bfgs2.cpp ions_move_cg.cpp ions_move_sd.cpp ions_move_methods.cpp diff --git a/source/source_relax/bfgs.cpp b/source/source_relax/ions_move_bfgs2.cpp similarity index 94% rename from source/source_relax/bfgs.cpp rename to source/source_relax/ions_move_bfgs2.cpp index b7fbbe821a1..79fedd84db9 100644 --- a/source/source_relax/bfgs.cpp +++ b/source/source_relax/ions_move_bfgs2.cpp @@ -1,4 +1,4 @@ -#include "bfgs.h" +#include "ions_move_bfgs2.h" #include "source_base/module_external/lapack_connector.h" #include "source_io/module_parameter/parameter.h" #include "ions_move_basic.h" @@ -7,7 +7,7 @@ #include "source_cell/print_cell.h" // lanshuyue add 2025-06-19 //! initialize H0、H、pos0、force0、force -void BFGS::allocate(const int _size) +void Ions_Move_BFGS2::allocate(const int _size) { assert(_size > 0); alpha=70;//default value in ase is 70 @@ -34,7 +34,7 @@ void BFGS::allocate(const int _size) } -void BFGS::relax_step(const ModuleBase::matrix& _force,UnitCell& ucell) +void Ions_Move_BFGS2::relax_step(const ModuleBase::matrix& _force,UnitCell& ucell) { if(!is_initialized) { @@ -84,7 +84,7 @@ void BFGS::relax_step(const ModuleBase::matrix& _force,UnitCell& ucell) unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,GlobalV::ofs_running); } -void BFGS::GetPos(UnitCell& ucell,std::vector>& pos) +void Ions_Move_BFGS2::GetPos(UnitCell& ucell,std::vector>& pos) { assert(pos.size() == ucell.nat); int k=0; @@ -100,7 +100,7 @@ void BFGS::GetPos(UnitCell& ucell,std::vector>& pos) } } -void BFGS::GetPostaud(UnitCell& ucell, +void Ions_Move_BFGS2::GetPostaud(UnitCell& ucell, std::vector>& pos_taud) { assert(pos_taud.size() == ucell.nat); @@ -117,7 +117,7 @@ void BFGS::GetPostaud(UnitCell& ucell, } } -void BFGS::PrepareStep(std::vector>& force, +void Ions_Move_BFGS2::PrepareStep(std::vector>& force, std::vector>& pos, std::vector>& H, std::vector& pos0, @@ -177,7 +177,7 @@ void BFGS::PrepareStep(std::vector>& force, force0 = ReshapeMToV(force); } -void BFGS::Update(std::vector& pos, +void Ions_Move_BFGS2::Update(std::vector& pos, std::vector& force, std::vector>& H, UnitCell& ucell) @@ -253,7 +253,7 @@ void BFGS::Update(std::vector& pos, H = MSubM(H, term4); } -void BFGS::DetermineStep(std::vector& steplength, +void Ions_Move_BFGS2::DetermineStep(std::vector& steplength, std::vector>& dpos, double& maxstep) { @@ -273,7 +273,7 @@ void BFGS::DetermineStep(std::vector& steplength, } } -void BFGS::UpdatePos(UnitCell& ucell) +void Ions_Move_BFGS2::UpdatePos(UnitCell& ucell) { double a[3*size]; for(int i=0;iMAddM(pos, dpos);*/ } -void BFGS::CalculateLargestGrad(const ModuleBase::matrix& _force,UnitCell& ucell) +void Ions_Move_BFGS2::CalculateLargestGrad(const ModuleBase::matrix& _force,UnitCell& ucell) { std::vector grad= std::vector(3*size, 0.0); int iat = 0; @@ -361,7 +361,7 @@ void BFGS::CalculateLargestGrad(const ModuleBase::matrix& _force,UnitCell& ucell } } -void BFGS::IsRestrain() +void Ions_Move_BFGS2::IsRestrain() { Ions_Move_Basic::converged = largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A #include @@ -10,7 +10,7 @@ #include "source_cell/unitcell.h" -class BFGS +class Ions_Move_BFGS2 { public: void allocate(const int _size);//initialize parameters @@ -46,4 +46,4 @@ class BFGS }; -#endif // BFGS_H +#endif // IONS_MOVE_BFGS2_H diff --git a/source/source_relax/ions_move_methods.cpp b/source/source_relax/ions_move_methods.cpp index 15f27d67d33..db485f4c09e 100644 --- a/source/source_relax/ions_move_methods.cpp +++ b/source/source_relax/ions_move_methods.cpp @@ -31,7 +31,7 @@ void Ions_Move_Methods::allocate(const int &natom) else if (Ions_Move_Basic::relax_method[0] == "cg_bfgs") { this->cg.allocate(); - this->bfgs.allocate(); // added by pengfei 13-8-8 + this->bfgs.allocate(); } else if(Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] == "1") { diff --git a/source/source_relax/ions_move_methods.h b/source/source_relax/ions_move_methods.h index cdddc4fdd61..b9b4e28611e 100644 --- a/source/source_relax/ions_move_methods.h +++ b/source/source_relax/ions_move_methods.h @@ -5,7 +5,7 @@ #include "ions_move_bfgs.h" #include "ions_move_cg.h" #include "ions_move_sd.h" -#include "bfgs.h" +#include "ions_move_bfgs2.h" #include "lbfgs.h" class Ions_Move_Methods @@ -47,7 +47,7 @@ class Ions_Move_Methods Ions_Move_BFGS bfgs; Ions_Move_CG cg; Ions_Move_SD sd; - BFGS bfgs_trad; + Ions_Move_BFGS2 bfgs_trad; LBFGS lbfgs; }; #endif diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index 78b343efd81..2c970e3a451 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -6,7 +6,7 @@ #include "source_esolver/esolver_ks.h" #include "relax_sync.h" #include "relax_nsync.h" -#include "bfgs.h" +#include "ions_move_bfgs2.h" #include "source_io/module_parameter/input_parameter.h" class Relax_Driver @@ -32,7 +32,7 @@ class Relax_Driver // old relaxation method Relax_old rl_old; - BFGS bfgs_trad; + Ions_Move_BFGS2 bfgs_trad; }; diff --git a/source/source_relax/test/bfgs_test.cpp b/source/source_relax/test/bfgs_test.cpp index a90c6b4ed75..81852def15f 100644 --- a/source/source_relax/test/bfgs_test.cpp +++ b/source/source_relax/test/bfgs_test.cpp @@ -4,7 +4,7 @@ #include "for_test.h" #define private public -#include "source_relax/bfgs.h" +#include "source_relax/ions_move_bfgs2.h" #undef private #define private public @@ -14,12 +14,12 @@ #include "source_relax/ions_move_basic.h" // for Ions_Move_Basic static members /************************************************ - * unit tests for BFGS (no MockUnitCell) + * unit tests for Ions_Move_BFGS2 (no MockUnitCell) ***********************************************/ class BFGSTest : public ::testing::Test { protected: - BFGS bfgs; + Ions_Move_BFGS2 bfgs; void SetUp() override { // Initialize variables before each test From 0ca3ecb899b802bb4d0e7442cad9f79e8be560c3 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Tue, 9 Jun 2026 13:48:48 +0800 Subject: [PATCH 08/50] fix --- source/source_relax/test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/source_relax/test/CMakeLists.txt b/source/source_relax/test/CMakeLists.txt index 777e24d7cf9..2c19c41ff48 100644 --- a/source/source_relax/test/CMakeLists.txt +++ b/source/source_relax/test/CMakeLists.txt @@ -61,7 +61,7 @@ AddTest( AddTest( TARGET MODULE_RELAX_bfgs_test LIBS parameter ${math_libs} base device - SOURCES bfgs_test.cpp ../bfgs.cpp ../ions_move_basic.cpp ../matrix_methods.cpp ${cell_source_files} + SOURCES bfgs_test.cpp ../ions_move_bfgs2.cpp ../ions_move_basic.cpp ../matrix_methods.cpp ${cell_source_files} ) AddTest( From bdb057a07e7ac938eb2233300733057e1bfa88a1 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Tue, 9 Jun 2026 14:00:42 +0800 Subject: [PATCH 09/50] add relax_data --- source/Makefile.Objects | 3 +- source/source_relax/CMakeLists.txt | 1 + source/source_relax/relax_data.cpp | 18 +++++++++++ source/source_relax/relax_data.h | 51 ++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 source/source_relax/relax_data.cpp create mode 100644 source/source_relax/relax_data.h diff --git a/source/Makefile.Objects b/source/Makefile.Objects index e1d14749d8c..e236a79fe2a 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -460,7 +460,8 @@ OBJS_PW=fft_bundle.o\ pw_transform.o\ pw_transform_k.o\ -OBJS_RELAXATION=bfgs_basic.o\ +OBJS_RELAXATION=relax_data.o\ + bfgs_basic.o\ relax_driver.o\ ions_move_basic.o\ ions_move_bfgs.o\ diff --git a/source/source_relax/CMakeLists.txt b/source/source_relax/CMakeLists.txt index 87aa8d1c3b3..b98170befdf 100644 --- a/source/source_relax/CMakeLists.txt +++ b/source/source_relax/CMakeLists.txt @@ -1,6 +1,7 @@ add_library( relax OBJECT + relax_data.cpp relax_driver.cpp relax_sync.cpp line_search.cpp diff --git a/source/source_relax/relax_data.cpp b/source/source_relax/relax_data.cpp new file mode 100644 index 00000000000..54c4e1a118f --- /dev/null +++ b/source/source_relax/relax_data.cpp @@ -0,0 +1,18 @@ +#include "relax_data.h" + +int Relax_Data::dim = 0; +bool Relax_Data::converged = false; +double Relax_Data::largest_grad = 0.0; +int Relax_Data::istep = 0; +double Relax_Data::ediff = 0.0; +double Relax_Data::etot = 0.0; +double Relax_Data::etot_p = 0.0; + +void Relax_Data::allocate(const int dim_in) { + pos.resize(dim_in, 0.0); + grad.resize(dim_in, 0.0); + move.resize(dim_in, 0.0); + pos_p.resize(dim_in, 0.0); + grad_p.resize(dim_in, 0.0); + move_p.resize(dim_in, 0.0); +} \ No newline at end of file diff --git a/source/source_relax/relax_data.h b/source/source_relax/relax_data.h new file mode 100644 index 00000000000..23caa55606e --- /dev/null +++ b/source/source_relax/relax_data.h @@ -0,0 +1,51 @@ +#ifndef RELAX_DATA_H +#define RELAX_DATA_H + +#include + +/** + * @brief Unified data structure for geometry optimization algorithms. + * + * This class provides a common data container for all relaxation methods + * (BFGS, CG, SD, etc.) to share and reuse key variables like positions, + * gradients, and move vectors. It serves as the single source of truth + * for optimization state across different algorithms. + */ +class Relax_Data { +public: + /** + * @brief Default constructor. + */ + Relax_Data() = default; + + /** + * @brief Default destructor. + */ + ~Relax_Data() = default; + + /** + * @brief Allocate memory for data vectors. + * @param dim_in Dimension of the optimization problem (3 * number of atoms). + */ + void allocate(const int dim_in); + + // Static members - shared global state across all relaxation instances + static int dim; ///< Dimension of free variables (3 * number of atoms) + static bool converged; ///< Convergence flag: true if optimization is converged + static double largest_grad; ///< Largest gradient component (force) in current step + static int istep; ///< Current iteration step index + static double ediff; ///< Energy difference from previous step (etot - etot_p) + static double etot; ///< Total energy of current step + static double etot_p; ///< Total energy of previous step + + // Instance members - per-iteration data + std::vector pos; ///< Current atomic positions in Bohr + std::vector grad; ///< Current gradient (negative force) in Ry/Bohr + std::vector move; ///< Displacement vector for next step + + std::vector pos_p; ///< Previous atomic positions + std::vector grad_p; ///< Previous gradient + std::vector move_p; ///< Previous displacement +}; + +#endif \ No newline at end of file From 73edf35c57a54c0e8e7252d01f541434b6cad507 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Tue, 9 Jun 2026 14:10:15 +0800 Subject: [PATCH 10/50] update --- source/source_relax/ions_move_basic.cpp | 11 +-- source/source_relax/ions_move_basic.h | 95 ++++++++++++++------ source/source_relax/lattice_change_basic.cpp | 13 +-- source/source_relax/lattice_change_basic.h | 82 ++++++++++------- 4 files changed, 124 insertions(+), 77 deletions(-) diff --git a/source/source_relax/ions_move_basic.cpp b/source/source_relax/ions_move_basic.cpp index 5eea695ceaf..c2b3d0cd9c8 100644 --- a/source/source_relax/ions_move_basic.cpp +++ b/source/source_relax/ions_move_basic.cpp @@ -6,23 +6,14 @@ #include "source_cell/update_cell.h" #include "source_cell/print_cell.h" -int Ions_Move_Basic::dim = 0; -bool Ions_Move_Basic::converged = false; -double Ions_Move_Basic::largest_grad = 0.0; +// Ions-specific parameters (shared variables are in Relax_Data) int Ions_Move_Basic::update_iter = 0; -int Ions_Move_Basic::istep = 0; - -double Ions_Move_Basic::ediff = 0.0; -double Ions_Move_Basic::etot = 0.0; -double Ions_Move_Basic::etot_p = 0.0; - double Ions_Move_Basic::trust_radius = 0.0; double Ions_Move_Basic::trust_radius_old = 0.0; double Ions_Move_Basic::relax_bfgs_rmax = -1.0; // default is 0.8 double Ions_Move_Basic::relax_bfgs_rmin = -1.0; // default is 1e-5 double Ions_Move_Basic::relax_bfgs_init = -1.0; // default is 0.5 double Ions_Move_Basic::best_xxx = 1.0; - int Ions_Move_Basic::out_stru = 0; std::vector Ions_Move_Basic::relax_method = {"bfgs","2"}; diff --git a/source/source_relax/ions_move_basic.h b/source/source_relax/ions_move_basic.h index e26acbba2fa..c852881a9af 100644 --- a/source/source_relax/ions_move_basic.h +++ b/source/source_relax/ions_move_basic.h @@ -1,48 +1,91 @@ #ifndef IONS_MOVE_BASIC_H #define IONS_MOVE_BASIC_H +#include "relax_data.h" #include "source_base/matrix.h" #include "source_cell/unitcell.h" +/** + * @namespace Ions_Move_Basic + * @brief Basic utilities and shared state for ionic relaxation algorithms. + * + * This namespace provides common functions and parameters used by all + * ion movement methods (BFGS, CG, SD, etc.). It shares core state variables + * through references to Relax_Data, ensuring consistent data across different + * optimization algorithms. + */ namespace Ions_Move_Basic { -extern int dim; // dimension of the free variables -extern bool converged; // converged force or not -extern double largest_grad; // largest gradient among the forces -extern int update_iter; // number of successfully updated iterations -extern int istep; // index of ionic steps -extern double ediff; // energy difference compared to last step -extern double etot; // total energy of this step -extern double etot_p; // total energy of last step - -extern double trust_radius; // trust radius now -extern double trust_radius_old; // old trust radius -extern double relax_bfgs_rmax; // max value of trust radius -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 initial step length -extern std::vector relax_method; // relaxation method -extern int out_stru; // output the structure or not - -// setup the gradient, all the same for any geometry optimization methods. +// Shared state variables (referenced from Relax_Data for unified data sharing) +static int& dim = Relax_Data::dim; ///< Dimension of free variables (3 * number of atoms) +static bool& converged = Relax_Data::converged; ///< Convergence flag +static double& largest_grad = Relax_Data::largest_grad; ///< Largest gradient component +static int& istep = Relax_Data::istep; ///< Current ionic step index +static double& ediff = Relax_Data::ediff; ///< Energy difference from previous step +static double& etot = Relax_Data::etot; ///< Total energy of current step +static double& etot_p = Relax_Data::etot_p; ///< Total energy of previous step + +// Ions-specific parameters (not shared with lattice change) +extern int update_iter; ///< Number of successfully updated iterations +extern double trust_radius; ///< Current trust radius +extern double trust_radius_old; ///< Previous trust radius +extern double relax_bfgs_rmax; ///< Maximum trust radius (default: 0.8 Bohr) +extern double relax_bfgs_rmin; ///< Minimum trust radius (default: 1e-5 Bohr) +extern double relax_bfgs_init; ///< Initial trust radius (default: 0.5 Bohr) +extern double best_xxx; ///< Last step length from CG, used as BFGS initial guess +extern std::vector relax_method; ///< Relaxation method settings +extern int out_stru; ///< Structure output flag + +/** + * @brief Setup gradient from atomic forces. + * @param ucell Unit cell containing atomic information + * @param force Force matrix (nat x 3) + * @param pos Output position array (dimension: dim) + * @param grad Output gradient array (dimension: dim) + */ void setup_gradient(const UnitCell &ucell, const ModuleBase::matrix &force, double *pos, double *grad); -// move the atom positions, considering the periodic boundary condition. +/** + * @brief Move atoms according to displacement vector. + * @param ucell Unit cell to update + * @param move Displacement vector (dimension: dim) + * @param pos Current position array (dimension: dim) + */ void move_atoms(UnitCell &ucell, double *move, double *pos); -// check the converged conditions ( if largest gradient is smaller than the threshold ) +/** + * @brief Check convergence based on gradient threshold. + * @param ucell Unit cell containing lattice information + * @param grad Gradient array (dimension: dim) + */ void check_converged(const UnitCell &ucell, const double *grad); -// terminate the geometry optimization. +/** + * @brief Terminate geometry optimization and output results. + * @param ucell Unit cell to output + */ void terminate(const UnitCell &ucell); -// setup the total energy, keep the new energy or not. +/** + * @brief Update energy values and compute energy difference. + * @param energy_in Input energy value + * @param judgement Flag for SD method (true) or BFGS (false) + */ void setup_etot(const double &energy_in, const bool judgement); -double dot_func(const double *a, const double *b, const int &dim); +/** + * @brief Compute dot product of two vectors. + * @param a First vector + * @param b Second vector + * @param dim_in Dimension of vectors + * @return Dot product value + */ +double dot_func(const double *a, const double *b, const int &dim_in); -// third order interpolation scheme +/** + * @brief Third-order polynomial interpolation for line search. + */ void third_order(); } // namespace Ions_Move_Basic -#endif +#endif \ No newline at end of file diff --git a/source/source_relax/lattice_change_basic.cpp b/source/source_relax/lattice_change_basic.cpp index 1bc41ce6238..6c2ca4b68f2 100644 --- a/source/source_relax/lattice_change_basic.cpp +++ b/source/source_relax/lattice_change_basic.cpp @@ -6,19 +6,10 @@ #include "source_io/module_parameter/parameter.h" #include "source_cell/update_cell.h" -int Lattice_Change_Basic::dim = 0; -bool Lattice_Change_Basic::converged = true; -double Lattice_Change_Basic::largest_grad = 0.0; +// Lattice-specific parameters (shared variables are in Relax_Data) int Lattice_Change_Basic::update_iter = 0; -int Lattice_Change_Basic::istep = 0; int Lattice_Change_Basic::stress_step = 0; - -double Lattice_Change_Basic::ediff = 0.0; -double Lattice_Change_Basic::etot = 0.0; -double Lattice_Change_Basic::etot_p = 0.0; - -// 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 +double Lattice_Change_Basic::lattice_change_ini = 0.01; // default is 0.01 std::string Lattice_Change_Basic::fixed_axes = "None"; void Lattice_Change_Basic::setup_gradient(const UnitCell &ucell, double *lat, double *grad, ModuleBase::matrix &stress) diff --git a/source/source_relax/lattice_change_basic.h b/source/source_relax/lattice_change_basic.h index 263c7bd5ca0..db5d6de1a35 100644 --- a/source/source_relax/lattice_change_basic.h +++ b/source/source_relax/lattice_change_basic.h @@ -1,48 +1,70 @@ #ifndef LATTICE_CHANGE_BASIC_H #define LATTICE_CHANGE_BASIC_H +#include "relax_data.h" #include "source_base/matrix.h" #include "source_cell/unitcell.h" +/** + * @namespace Lattice_Change_Basic + * @brief Basic utilities and shared state for lattice relaxation algorithms. + * + * This namespace provides common functions and parameters used by lattice + * optimization methods. It shares core state variables through references to + * Relax_Data, ensuring consistent data across different optimization algorithms. + */ namespace Lattice_Change_Basic { -extern int dim; // dimension of the free variables, -extern bool converged; // converged force or not, -extern double largest_grad; // largest gradient among the forces, -extern int update_iter; // number of sucesfully updated iterations, -extern int istep; // index of ionic steps, -extern int stress_step; // index of stress step -extern double ediff; // energy difference compared to last step, -extern double etot; // total energy of this step, -extern double etot_p; // total energy of last step, - -extern double lattice_change_ini; // initial value of trust radius, -extern std::string fixed_axes; // convert from INPUT.fixed_axes - -//---------------------------------------------------------------------------- -// setup the gradient, all the same for any geometry optimization methods. -//---------------------------------------------------------------------------- +// Shared state variables (referenced from Relax_Data for unified data sharing) +static int& dim = Relax_Data::dim; ///< Dimension of free variables (9 for full lattice) +static bool& converged = Relax_Data::converged; ///< Convergence flag +static double& largest_grad = Relax_Data::largest_grad; ///< Largest gradient component +static int& istep = Relax_Data::istep; ///< Current ionic step index +static double& ediff = Relax_Data::ediff; ///< Energy difference from previous step +static double& etot = Relax_Data::etot; ///< Total energy of current step +static double& etot_p = Relax_Data::etot_p; ///< Total energy of previous step + +// Lattice-specific parameters (not shared with ion movement) +extern int update_iter; ///< Number of successfully updated iterations +extern int stress_step; ///< Index of stress optimization step +extern double lattice_change_ini; ///< Initial trust radius for lattice change (default: 0.01) +extern std::string fixed_axes; ///< Fixed axes constraint ("None", "shape", "volume", or specific axes) + +/** + * @brief Setup gradient from stress tensor. + * @param ucell Unit cell containing lattice information + * @param lat Output lattice vector array (9 elements: e11, e12, e13, e21, e22, e23, e31, e32, e33) + * @param grad Output gradient array (9 elements) + * @param stress Stress tensor (3x3 matrix) + */ void setup_gradient(const UnitCell &ucell, double *lat, double *grad, ModuleBase::matrix &stress); -//---------------------------------------------------------------------------- -// move the atom positions, considering the periodic boundary condition. -//---------------------------------------------------------------------------- +/** + * @brief Update lattice vectors according to displacement. + * @param ucell Unit cell to update + * @param move Displacement vector for lattice change (9 elements) + * @param lat Current lattice vectors (9 elements) + */ void change_lattice(UnitCell &ucell, double *move, double *lat); -//---------------------------------------------------------------------------- -// check the converged conditions ( if largest gradient is smaller than -// the threshold) -//---------------------------------------------------------------------------- +/** + * @brief Check convergence based on stress threshold. + * @param ucell Unit cell containing lattice constraints + * @param stress Stress tensor (3x3 matrix) + * @param grad Gradient array (9 elements) + */ void check_converged(const UnitCell &ucell, ModuleBase::matrix &stress, double *grad); -//---------------------------------------------------------------------------- -// terminate the geometry optimization. -//---------------------------------------------------------------------------- +/** + * @brief Terminate lattice optimization and output results. + */ void terminate(void); -//---------------------------------------------------------------------------- -// setup the total energy, keep the new energy or not. -//---------------------------------------------------------------------------- +/** + * @brief Update energy values and compute energy difference. + * @param energy_in Input energy value + * @param judgement Flag for SD method (true) or BFGS (false) + */ void setup_etot(const double &energy_in, const bool judgement); } // namespace Lattice_Change_Basic -#endif +#endif \ No newline at end of file From 44eb6410a9eec19767ca6e8599e98f6b85956341 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Tue, 9 Jun 2026 14:22:12 +0800 Subject: [PATCH 11/50] update --- source/Makefile.Objects | 1 + source/source_relax/CMakeLists.txt | 1 + source/source_relax/cg_base.cpp | 213 +++++++++++++++++++++++++++++ source/source_relax/cg_base.h | 83 +++++++++++ 4 files changed, 298 insertions(+) create mode 100644 source/source_relax/cg_base.cpp create mode 100644 source/source_relax/cg_base.h diff --git a/source/Makefile.Objects b/source/Makefile.Objects index e236a79fe2a..fc49ec2227a 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -461,6 +461,7 @@ OBJS_PW=fft_bundle.o\ pw_transform_k.o\ OBJS_RELAXATION=relax_data.o\ + cg_base.o\ bfgs_basic.o\ relax_driver.o\ ions_move_basic.o\ diff --git a/source/source_relax/CMakeLists.txt b/source/source_relax/CMakeLists.txt index b98170befdf..692e9315fb9 100644 --- a/source/source_relax/CMakeLists.txt +++ b/source/source_relax/CMakeLists.txt @@ -2,6 +2,7 @@ add_library( relax OBJECT relax_data.cpp + cg_base.cpp relax_driver.cpp relax_sync.cpp line_search.cpp diff --git a/source/source_relax/cg_base.cpp b/source/source_relax/cg_base.cpp new file mode 100644 index 00000000000..9fee5024d95 --- /dev/null +++ b/source/source_relax/cg_base.cpp @@ -0,0 +1,213 @@ +#include "cg_base.h" +#include +#include "source_base/global_function.h" + +void CG_Base::setup_cg_grad(const int dim, double *grad, const double *grad0, + double *cg_grad, const double *cg_grad0, + const int &ncggrad, int &flag) +{ + ModuleBase::TITLE("CG_Base", "setup_cg_grad"); + double gamma = 0.0; + + if (ncggrad % 10000 == 0 || flag == 2) + { + for (int i = 0; i < dim; i++) + { + cg_grad[i] = grad[i]; + } + } + else + { + double gp_gp = 0.0; // grad_p.grad_p + double gg = 0.0; // grad.grad + double g_gp = 0.0; // grad_p.grad + double cgp_gp = 0.0; // cg_grad_p.grad_p + double cgp_g = 0.0; // cg_grad_p.grad + for (int i = 0; i < dim; i++) + { + gp_gp += grad0[i] * grad0[i]; + gg += grad[i] * grad[i]; + g_gp += grad0[i] * grad[i]; + cgp_gp += cg_grad0[i] * grad0[i]; + cgp_g += cg_grad0[i] * grad[i]; + } + + const double gamma1 = gg / gp_gp; // FR + const double gamma2 = (gg - g_gp) / gp_gp; // PRP + + if (gamma1 < 0.5) + { + gamma = gamma1; + } + else + { + gamma = gamma2; + } + + for (int i = 0; i < dim; i++) + { + cg_grad[i] = grad[i] + gamma * cg_grad0[i]; + } + } +} + +void CG_Base::setup_move(const int dim, double *move, double *cg_gradn, const double &trust_radius) +{ + ModuleBase::TITLE("CG_Base", "setup_move"); + for (int i = 0; i < dim; ++i) + { + move[i] = -cg_gradn[i] * trust_radius; + } +} + +void CG_Base::Brent(double &fa, double &fb, double &fc, + double &xa, double &xb, double &xc, + double &best_x, double &xpt) +{ + ModuleBase::TITLE("CG_Base", "Brent"); + double dmove = 0.0; + double tmp = 0.0; + double k2 = 0.0; + double k1 = 0.0; + double k0 = 0.0; + double xnew1 = 0.0; + double xnew2 = 0.0; + double ecalnew1 = 0.0; + double ecalnew2 = 0.0; + + if ((fa * fb) > 0) + { + dmove = (xc * fa - xa * fc) / (fa - fc); + if (dmove > 4 * xc) + { + dmove = 4 * xc; + } + xb = xc; + fb = fc; + } + else + { + k2 = -((fb - fc) / (xb - xc) - (fa - fc) / (xa - xc)) / (xa - xb); + k1 = (fa - fc) / (xa - xc) - k2 * (xa + xc); + k0 = fa - k1 * xa - k2 * xa * xa; + xnew1 = (-k1 - sqrt(k1 * k1 - 4 * k2 * k0)) / (2 * k2); + xnew2 = (-k1 + sqrt(k1 * k1 - 4 * k2 * k0)) / (2 * k2); + + if (xnew1 > xnew2) + { + tmp = xnew2; + xnew2 = xnew1; + xnew1 = tmp; + } + + ecalnew1 = k2 * xnew1 * xnew1 * xnew1 / 3 + k1 * xnew1 * xnew1 / 2 + k0 * xnew1; + ecalnew2 = k2 * xnew2 * xnew2 * xnew2 / 3 + k1 * xnew2 * xnew2 / 2 + k0 * xnew2; + dmove = xnew1; + + if (ecalnew1 > ecalnew2) + { + dmove = xnew2; + } + if (dmove < 0) + { + dmove = 2 * xc; + } + if (fa * fc > 0) + { + xa = xc; + fa = fc; + } + if (fb * fc > 0) + { + xb = xc; + fb = fc; + } + } + + best_x = dmove - xpt; + xpt = dmove; + xc = dmove; +} + +void CG_Base::f_cal(const int dim, const double *g0, const double *g1, double &f_value) +{ + ModuleBase::TITLE("CG_Base", "f_cal"); + double hv0 = 0.0; + double hel = 0.0; + for (int i = 0; i < dim; i++) + { + hel += g0[i] * g1[i]; + hv0 += g0[i] * g0[i]; + } + f_value = hel / sqrt(hv0); +} + +void CG_Base::third_order(const double &e0, const double &e1, + const double &fa, const double &fb, + const double x, double &best_x) +{ + ModuleBase::TITLE("CG_Base", "third_order"); + double k3 = 0.0; + double k2 = 0.0; + double k1 = 0.0; + double dmoveh = 0.0; + double dmove1 = 0.0; + double dmove2 = 0.0; + double dmove = 0.0; + double ecal1 = 0.0; + double ecal2 = 0.0; + + k3 = 3 * ((fb + fa) * x - 2 * (e1 - e0)) / (x * x * x); + k2 = (fb - fa) / x - k3 * x; + k1 = fa; + + dmoveh = x * fb / (fa - fb); + dmove1 = -k2 * (1 - sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); + dmove2 = -k2 * (1 + sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); + + if ((std::abs(k3 / k1) < 0.01) || ((k1 * k3 / (k2 * k2)) >= 0.25)) + { + dmove = dmoveh; + } + else + { + dmove1 = -k2 * (1 - sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); + dmove2 = -k2 * (1 + sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); + ecal1 = k3 * dmove1 * dmove1 * dmove1 / 3 + k2 * dmove1 * dmove1 / 2 + k1 * dmove1; + ecal2 = k3 * dmove2 * dmove2 * dmove2 / 3 + k2 * dmove2 * dmove2 / 2 + k1 * dmove2; + if (ecal2 > ecal1) + { + dmove = dmove1 - x; + } + else + { + dmove = dmove2 - x; + } + + if (k3 < 0) + { + dmove = dmoveh; + } + } + + best_x = dmove; +} + +void CG_Base::normalize(const int dim, double *cg_gradn, const double *cg_grad) +{ + ModuleBase::TITLE("CG_Base", "normalize"); + double norm = 0.0; + for (int i = 0; i < dim; ++i) + { + norm += pow(cg_grad[i], 2); + } + norm = sqrt(norm); + + if (norm != 0.0) + { + for (int i = 0; i < dim; ++i) + { + cg_gradn[i] = cg_grad[i] / norm; + } + } +} \ No newline at end of file diff --git a/source/source_relax/cg_base.h b/source/source_relax/cg_base.h new file mode 100644 index 00000000000..ce245830ce4 --- /dev/null +++ b/source/source_relax/cg_base.h @@ -0,0 +1,83 @@ +#ifndef CG_BASE_H +#define CG_BASE_H + +/** + * @class CG_Base + * @brief Base class for conjugate gradient optimization algorithms. + * + * This class provides common CG utility functions that can be shared between + * different optimization implementations (ions movement and lattice change). + * The functions are designed to be independent of specific data sources. + */ +class CG_Base { +protected: + /** + * @brief Setup conjugate gradient direction. + * @param dim Dimension of the optimization problem + * @param grad Current gradient + * @param grad0 Previous gradient + * @param cg_grad Output CG direction + * @param cg_grad0 Previous CG direction + * @param ncggrad CG iteration counter + * @param flag Restart flag + */ + void setup_cg_grad(const int dim, double *grad, const double *grad0, + double *cg_grad, const double *cg_grad0, + const int &ncggrad, int &flag); + + /** + * @brief Calculate movement vector from CG direction. + * @param dim Dimension of the optimization problem + * @param move Output movement vector + * @param cg_gradn Normalized CG direction + * @param trust_radius Step size limit + */ + void setup_move(const int dim, double *move, double *cg_gradn, const double &trust_radius); + + /** + * @brief Brent's method for one-dimensional minimization. + * @param fa Function value at xa + * @param fb Function value at xb + * @param fc Function value at xc + * @param xa Left bound + * @param xb Middle point + * @param xc Right bound + * @param best_x Output best step length + * @param xpt Previous best point + */ + void Brent(double &fa, double &fb, double &fc, + double &xa, double &xb, double &xc, + double &best_x, double &xpt); + + /** + * @brief Calculate projection of gradient onto search direction. + * @param dim Dimension of vectors + * @param g0 First vector (usually search direction) + * @param g1 Second vector (usually gradient) + * @param f_value Output projection value + */ + void f_cal(const int dim, const double *g0, const double *g1, double &f_value); + + /** + * @brief Third-order polynomial interpolation for line search. + * @param e0 Energy at previous step + * @param e1 Energy at current step + * @param fa Gradient projection at previous step + * @param fb Gradient projection at current step + * @param x Current step length + * @param best_x Output optimal step length + */ + void third_order(const double &e0, const double &e1, + const double &fa, const double &fb, + const double x, double &best_x); + + /** + * @brief Normalize vector. + * @param dim Dimension of vector + * @param cg_gradn Output normalized vector + * @param cg_grad Input vector + */ + void normalize(const int dim, double *cg_gradn, const double *cg_grad); +}; + +#endif \ No newline at end of file From 499adf24bddc321c0be9f8df133ed75b10234bb9 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Tue, 9 Jun 2026 14:34:12 +0800 Subject: [PATCH 12/50] update --- source/source_relax/ions_move_cg.cpp | 488 +++++----------------- source/source_relax/ions_move_cg.h | 40 +- source/source_relax/lattice_change_cg.cpp | 473 +++++---------------- source/source_relax/lattice_change_cg.h | 31 +- 4 files changed, 217 insertions(+), 815 deletions(-) diff --git a/source/source_relax/ions_move_cg.cpp b/source/source_relax/ions_move_cg.cpp index 05e18c4b7f2..00a73f648d6 100644 --- a/source/source_relax/ions_move_cg.cpp +++ b/source/source_relax/ions_move_cg.cpp @@ -2,59 +2,26 @@ #include "ions_move_basic.h" #include "source_base/global_function.h" #include "source_base/global_variable.h" +#include using namespace Ions_Move_Basic; double Ions_Move_CG::RELAX_CG_THR = -1.0; // default is 0.5 -//=================== NOTES ======================== -// in vasp, it's like -// contolled by POTIM. -// the approximate minimum of the total energy -// is calculated from a cubic (or quadratic) -// interpolation taking into account the change -// of the total energy and the changes of forces. -// ( 3 pieces of information ) -// 1. trial step -// 2. corrector step using cubic or quadratic interpolation -// 3. Check the force and see if we need brent method interpolation. -// 4. a new trial step.... -// Brent's method is a complicated but popular -// root-finding algorithm combining the bisection method, -// the secant method and inverse quadratic interpolation -//=================== NOTES ======================== Ions_Move_CG::Ions_Move_CG() { - this->pos0 = nullptr; - this->grad0 = nullptr; - this->cg_grad0 = nullptr; - this->move0 = nullptr; -} - -Ions_Move_CG::~Ions_Move_CG() -{ - delete[] pos0; - delete[] grad0; - delete[] cg_grad0; - delete[] move0; + this->e0 = 0.0; } void Ions_Move_CG::allocate(void) { ModuleBase::TITLE("Ions_Move_CG", "allocate"); assert(dim > 0); - delete[] pos0; - delete[] grad0; - delete[] cg_grad0; - delete[] move0; - this->pos0 = new double[dim]; - this->grad0 = new double[dim]; - this->cg_grad0 = new double[dim]; - this->move0 = new double[dim]; - ModuleBase::GlobalFunc::ZEROS(pos0, dim); - ModuleBase::GlobalFunc::ZEROS(grad0, dim); - ModuleBase::GlobalFunc::ZEROS(cg_grad0, dim); - ModuleBase::GlobalFunc::ZEROS(move0, dim); + + this->pos0.resize(dim, 0.0); + this->grad0.resize(dim, 0.0); + this->cg_grad0.resize(dim, 0.0); + this->move0.resize(dim, 0.0); this->e0 = 0.0; } @@ -62,20 +29,9 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const { ModuleBase::TITLE("Ions_Move_CG", "start"); assert(dim > 0); - assert(pos0 != 0); - assert(grad0 != 0); - assert(cg_grad0 != 0); - assert(move0 != 0); - // sd , trial are two parameters, when sd=trial=true ,a new direction begins, when sd = false trial =true static bool sd = false; - - // a cubic interpolation is used to make the third point , - // when sa = trial = false , we use Brent to get the minimum point in this direction. static bool trial = false; - - // ncggrad is a parameter to control the cg method , every ten cg directions, - // we change the direction back to the steepest descent method static int ncggrad = 0; static double fa = 0.0; static double fb = 0.0; @@ -87,87 +43,73 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const static double steplength = 0.0; static double fmax = 0.0; static int nbrent = 0; - - // some arrays - double *pos = new double[dim]; - double *grad = new double[dim]; - double *cg_gradn = new double[dim]; - double *move = new double[dim]; - double *cg_grad = new double[dim]; + + std::vector pos(dim, 0.0); + std::vector grad(dim, 0.0); + std::vector cg_gradn(dim, 0.0); + std::vector move(dim, 0.0); + std::vector cg_grad(dim, 0.0); double best_x = 0.0; double fmin = 0.0; int flag = 0; - ModuleBase::GlobalFunc::ZEROS(pos, dim); - ModuleBase::GlobalFunc::ZEROS(grad, dim); - ModuleBase::GlobalFunc::ZEROS(move, dim); - ModuleBase::GlobalFunc::ZEROS(cg_grad, dim); - -CG_begin: - - if (Ions_Move_Basic::istep == 1) + while (true) { - steplength = Ions_Move_Basic::relax_bfgs_init; // read in the init trust radius - sd = true; - trial = true; - ncggrad = 0; - fa = 0.0; - fb = 0.0; - fc = 0.0; - xa = 0.0; - xb = 0.0; - xc = 0.0; - xpt = 0.0; - fmax = 0.0; - nbrent = 0; - } + if (Ions_Move_Basic::istep == 1) + { + steplength = Ions_Move_Basic::relax_bfgs_init; + sd = true; + trial = true; + ncggrad = 0; + fa = 0.0; + fb = 0.0; + fc = 0.0; + xa = 0.0; + xb = 0.0; + xc = 0.0; + xpt = 0.0; + fmax = 0.0; + nbrent = 0; + } - Ions_Move_Basic::setup_gradient(ucell, force, pos, grad); - // use energy_in and istep to setup etot and etot_old. - Ions_Move_Basic::setup_etot(etot_in, 0); - // use gradient and etot and etot_old to check - // if the result is converged. + Ions_Move_Basic::setup_gradient(ucell, force, pos.data(), grad.data()); + Ions_Move_Basic::setup_etot(etot_in, 0); + + if (flag == 0) + { + Ions_Move_Basic::check_converged(ucell, grad.data()); + } + if (Ions_Move_Basic::converged) + { + Ions_Move_Basic::terminate(ucell); + break; + } - if (flag == 0) - { - Ions_Move_Basic::check_converged(ucell, grad); - } - if (Ions_Move_Basic::converged) - { - Ions_Move_Basic::terminate(ucell); - } - else - { if (sd) { e0 = etot_in; - setup_cg_grad(grad, - grad0, - cg_grad, - cg_grad0, - ncggrad, - flag); // we use the last direction ,the last grad and the grad now to get the direction now + CG_Base::setup_cg_grad(dim, grad.data(), grad0.data(), cg_grad.data(), cg_grad0.data(), ncggrad, flag); ncggrad++; - normalize(cg_gradn, cg_grad, dim); - setup_move(move0, cg_gradn, steplength); // move the atom position - Ions_Move_Basic::move_atoms(ucell, move0, pos); + CG_Base::normalize(dim, cg_gradn.data(), cg_grad.data()); + CG_Base::setup_move(dim, move0.data(), cg_gradn.data(), steplength); + Ions_Move_Basic::move_atoms(ucell, move0.data(), pos.data()); - for (int i = 0; i < dim; i++) // grad0 ,cg_grad0 are used to store the grad and cg_grad for the future using + for (int i = 0; i < dim; i++) { grad0[i] = grad[i]; cg_grad0[i] = cg_grad[i]; } - f_cal(move0, move0, dim, xb); // xb = trial steplength - f_cal(move0, grad, dim, fa); // fa is the projection force in this direction + CG_Base::f_cal(dim, move0.data(), move0.data(), xb); + CG_Base::f_cal(dim, move0.data(), grad.data(), fa); fmax = fa; sd = false; if (Ions_Move_Basic::relax_method[0] == "cg_bfgs") { if (Ions_Move_Basic::largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A - < RELAX_CG_THR) // cg to bfgs by pengfei 13-8-8 + < RELAX_CG_THR) { Ions_Move_Basic::relax_method[0] = "bfgs"; Ions_Move_Basic::relax_method[1] = "1"; @@ -176,301 +118,75 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const } Ions_Move_Basic::relax_bfgs_init = xb; + break; } - else - { - if (trial) - { - double e1 = etot_in; - f_cal(move0, grad, dim, fb); - f_cal(move0, move0, dim, xb); - if ((std::abs(fb) < std::abs((fa) / 10.0))) - { - sd = true; - trial = true; - steplength = xb; - flag = 1; - goto CG_begin; - } - normalize(cg_gradn, cg_grad0, dim); - third_order(e0, e1, fa, fb, xb, best_x); // cubic interpolation - - if (best_x > 6 * xb || best_x < (-xb)) - { - best_x = 6 * xb; - } + if (trial) + { + double e1 = etot_in; + CG_Base::f_cal(dim, move0.data(), grad.data(), fb); + CG_Base::f_cal(dim, move0.data(), move0.data(), xb); - setup_move(move, cg_gradn, best_x); - Ions_Move_Basic::move_atoms(ucell, move, pos); - trial = false; - xa = 0; - f_cal(move0, move, dim, xc); - xc = xb + xc; - xpt = xc; - Ions_Move_Basic::relax_bfgs_init = xc; - } - else + if ((std::abs(fb) < std::abs((fa) / 10.0))) { - double xtemp, ftemp; - f_cal(move0, grad, dim, fc); - fmin = std::abs(fc); - nbrent++; - - if ((fmin < std::abs((fmax) / 10.0)) || (nbrent > 3)) - { - nbrent = 0; - sd = true; - trial = true; - steplength = xpt; - flag = 1; - goto CG_begin; - } - else - { - Brent(fa, fb, fc, xa, xb, xc, best_x, xpt); // Brent method - if (xc < 0) - { - sd = true; - trial = true; - steplength = xb; - flag = 2; - goto CG_begin; - } - - normalize(cg_gradn, cg_grad0, dim); - setup_move(move, cg_gradn, best_x); - Ions_Move_Basic::move_atoms(ucell, move, pos); - Ions_Move_Basic::relax_bfgs_init = xc; - } + sd = true; + trial = true; + steplength = xb; + flag = 1; + continue; } - } - } - delete[] cg_grad; - delete[] grad; - delete[] cg_gradn; - delete[] pos; - delete[] move; + CG_Base::normalize(dim, cg_gradn.data(), cg_grad0.data()); + CG_Base::third_order(e0, e1, fa, fb, xb, best_x); - return; -} - -void Ions_Move_CG::setup_cg_grad(double *grad, - const double *grad0, - double *cg_grad, - const double *cg_grad0, - const int &ncggrad, - int &flag) -{ - ModuleBase::TITLE("Ions_Move_CG", "setup_cg_grad"); - assert(Ions_Move_Basic::istep > 0); - double gamma; - double cg0_cg, cg0_cg0, cg0_g; + if (best_x > 6 * xb || best_x < (-xb)) + { + best_x = 6 * xb; + } - if (ncggrad % 10000 == 0 || flag == 2) - { - for (int i = 0; i < dim; i++) - { - cg_grad[i] = grad[i]; - } - } - else - { - double gp_gp = 0.0; // grad_p.grad_p - double gg = 0.0; // grad.grad - double g_gp = 0.0; // grad_p.grad - double cgp_gp = 0.0; // cg_grad_p.grad_p - double cgp_g = 0.0; // cg_grad_p.grad - for (int i = 0; i < dim; i++) - { - gp_gp += grad0[i] * grad0[i]; - gg += grad[i] * grad[i]; - g_gp += grad0[i] * grad[i]; - cgp_gp += cg_grad0[i] * grad0[i]; - cgp_g += cg_grad0[i] * grad[i]; + CG_Base::setup_move(dim, move.data(), cg_gradn.data(), best_x); + Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data()); + trial = false; + xa = 0; + CG_Base::f_cal(dim, move0.data(), move.data(), xc); + xc = xb + xc; + xpt = xc; + Ions_Move_Basic::relax_bfgs_init = xc; + break; } - assert(g_gp != 0.0); - const double gamma1 = gg / gp_gp; // FR - // const double gamma2 = -(gg - g_gp)/(cgp_g - cgp_gp); //CW - const double gamma2 = (gg - g_gp) / gp_gp; // PRP - // const double gamma = gg/cgp_gp; //D - // const double gamma = -gg/(cgp_g - cgp_gp); //D-Y - if (gamma1 < 0.5) - { - gamma = gamma1; - } - else - { - gamma = gamma2; - } + double xtemp = 0.0; + double ftemp = 0.0; + CG_Base::f_cal(dim, move0.data(), grad.data(), fc); + fmin = std::abs(fc); + nbrent++; - for (int i = 0; i < dim; i++) + if ((fmin < std::abs((fmax) / 10.0)) || (nbrent > 3)) { - // we can consider step as modified gradient. - cg_grad[i] = grad[i] + gamma * cg_grad0[i]; + nbrent = 0; + sd = true; + trial = true; + steplength = xpt; + flag = 1; + continue; } - } - return; -} -void Ions_Move_CG::third_order(const double &e0, - const double &e1, - const double &fa, - const double &fb, - const double x, - double &best_x) -{ - double k3, k2, k1; - double dmoveh, dmove1, dmove2, dmove, ecal1, ecal2; - - k3 = 3 * ((fb + fa) * x - 2 * (e1 - e0)) / (x * x * x); - k2 = (fb - fa) / x - k3 * x; - k1 = fa; - - dmoveh = x * fb / (fa - fb); - dmove1 = -k2 * (1 - sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); - dmove2 = -k2 * (1 + sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); - - if ((std::abs(k3 / k1) < 0.01) || ((k1 * k3 / (k2 * k2)) >= 0.25)) // this condition may be wrong - { - dmove = dmoveh; - } - else - { - dmove1 = -k2 * (1 - sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); - dmove2 = -k2 * (1 + sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); - ecal1 = k3 * dmove1 * dmove1 * dmove1 / 3 + k2 * dmove1 * dmove1 / 2 + k1 * dmove1; - ecal2 = k3 * dmove2 * dmove2 * dmove2 / 3 + k2 * dmove2 * dmove2 / 2 + k1 * dmove2; - if (ecal2 > ecal1) - dmove = dmove1 - x; - else - dmove = dmove2 - x; - - if (k3 < 0) - dmove = dmoveh; - } - - best_x = dmove; - return; -} - -void Ions_Move_CG::Brent(double &fa, - double &fb, - double &fc, - double &xa, - double &xb, - double &xc, - double &best_x, - double &xpt) -{ - double dmove; - double tmp; - double k2, k1, k0; - double xnew1, xnew2; - double ecalnew1, ecalnew2; - - if ((fa * fb) > 0) - { - dmove = (xc * fa - xa * fc) / (fa - fc); - if (dmove > 4 * xc) - // if(dmove > 4 * xc || dmove < 0) - { - dmove = 4 * xc; - } - xb = xc; - fb = fc; - } - else - { - k2 = -((fb - fc) / (xb - xc) - (fa - fc) / (xa - xc)) / (xa - xb); - k1 = (fa - fc) / (xa - xc) - k2 * (xa + xc); - k0 = fa - k1 * xa - k2 * xa * xa; - xnew1 = (-k1 - sqrt(k1 * k1 - 4 * k2 * k0)) / (2 * k2); - xnew2 = (-k1 + sqrt(k1 * k1 - 4 * k2 * k0)) / (2 * k2); - - if (xnew1 > xnew2) - { - tmp = xnew2; - xnew2 = xnew1; - xnew1 = tmp; - } - - ecalnew1 = k2 * xnew1 * xnew1 * xnew1 / 3 + k1 * xnew1 * xnew1 / 2 + k0 * xnew1; - ecalnew2 = k2 * xnew2 * xnew2 * xnew2 / 3 + k1 * xnew2 * xnew2 / 2 + k0 * xnew2; - dmove = xnew1; - - if (ecalnew1 > ecalnew2) - { - dmove = xnew2; - } - if (dmove < 0) - { - dmove = 2 * xc; // pengfei 14-6-5 - } - if (fa * fc > 0) + CG_Base::Brent(fa, fb, fc, xa, xb, xc, best_x, xpt); + if (xc < 0) { - xa = xc; - fa = fc; + sd = true; + trial = true; + steplength = xb; + flag = 2; + continue; } - if (fb * fc > 0) - { - xb = xc; - fb = fc; - } - } - - best_x = dmove - xpt; - xpt = dmove; - xc = dmove; - return; -} - -void Ions_Move_CG::f_cal(const double *g0, const double *g1, const int &dim, double &f_value) -{ - double hv0, hel; - hel = 0; - hv0 = 0; - for (int i = 0; i < dim; i++) - { - hel += g0[i] * g1[i]; - } - for (int i = 0; i < dim; i++) - { - hv0 += g0[i] * g0[i]; + CG_Base::normalize(dim, cg_gradn.data(), cg_grad0.data()); + CG_Base::setup_move(dim, move.data(), cg_gradn.data(), best_x); + Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data()); + Ions_Move_Basic::relax_bfgs_init = xc; + break; } - f_value = hel / sqrt(hv0); return; -} - -void Ions_Move_CG::setup_move(double *move, double *cg_gradn, const double &trust_radius) -{ - // movement using gradient and trust_radius. - for (int i = 0; i < dim; ++i) - { - move[i] = -cg_gradn[i] * trust_radius; - } - return; -} - -void Ions_Move_CG::normalize(double *cg_gradn, const double *cg_grad, int dim) -{ - double norm = 0.0; - for (int i = 0; i < dim; ++i) - { - norm += pow(cg_grad[i], 2); - } - norm = sqrt(norm); - - if (norm != 0.0) - { - for (int i = 0; i < dim; ++i) - { - cg_gradn[i] = cg_grad[i] / norm; - } - } - return; -} +} \ No newline at end of file diff --git a/source/source_relax/ions_move_cg.h b/source/source_relax/ions_move_cg.h index 6e77127ca52..d846219e8ec 100644 --- a/source/source_relax/ions_move_cg.h +++ b/source/source_relax/ions_move_cg.h @@ -3,42 +3,28 @@ #include "source_base/matrix.h" #include "source_cell/unitcell.h" -class Ions_Move_CG +#include "cg_base.h" +#include + +class Ions_Move_CG : public CG_Base { public: Ions_Move_CG(); - ~Ions_Move_CG(); + ~Ions_Move_CG() = default; void allocate(void); void start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot); static double RELAX_CG_THR; - int sd_step=0; - int cg_step=0; + int sd_step = 0; + int cg_step = 0; private: - double * pos0 = nullptr; - double * grad0 = nullptr; - double * cg_grad0 = nullptr; - double * move0 = nullptr; - double e0=0.0; - // setup gradients. - void setup_cg_grad(double *grad, - const double *grad0, - double *cg_grad, - const double *cg_grad0, - const int &ncggrad, - int &flag); // LiuXh fix bug of lpf, 20180515 - void setup_move(double *move, double *cg_gradn, const double &trust_radius); - void Brent(double &fa, double &fb, double &fc, double &xa, double &xb, double &xc, double &best_x, double &xpt); - void f_cal(const double *g0, const double *g1, const int &dim, double &f_value); - void third_order(const double &e0, - const double &e1, - const double &fa, - const double &fb, - const double x, - double &best_x); - void normalize(double *cg_gradn, const double *cg_grad, int dim); + std::vector pos0; + std::vector grad0; + std::vector cg_grad0; + std::vector move0; + double e0 = 0.0; }; -#endif +#endif \ No newline at end of file diff --git a/source/source_relax/lattice_change_cg.cpp b/source/source_relax/lattice_change_cg.cpp index d0172ba7845..601da813181 100644 --- a/source/source_relax/lattice_change_cg.cpp +++ b/source/source_relax/lattice_change_cg.cpp @@ -3,25 +3,10 @@ #include "lattice_change_basic.h" #include "source_base/global_function.h" #include "source_base/global_variable.h" +#include -// the 'dim' variable is defined in Lattice_Change_Basic using namespace Lattice_Change_Basic; -//=================== NOTES ======================== -// the approximate minimum of the total energy -// is calculated from a cubic (or quadratic) -// interpolation taking into account the change -// of the total energy and the changes of forces. -// ( 3 pieces of information ) -// 1. trial step -// 2. corrector step using cubic or quadratic interpolation -// 3. check the force and see if we need brent method interpolation. -// 4. a new trial step.... -// Brent's method is a complicated but popular -// root-finding algorithm combining the bisection method, -// the secant method and inverse quadratic interpolation -//=================== NOTES ======================== - Lattice_Change_CG::Lattice_Change_CG() { this->e0 = 0.0; @@ -30,7 +15,6 @@ Lattice_Change_CG::Lattice_Change_CG() void Lattice_Change_CG::allocate(void) { ModuleBase::TITLE("Lattice_Change_CG", "allocate"); - // mohan add 2021-02-07 assert(dim > 0); this->lat0.resize(dim, 0.0); @@ -48,423 +32,160 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ assert(grad0.size() == static_cast(dim)); assert(cg_grad0.size() == static_cast(dim)); assert(move0.size() == static_cast(dim)); - - // sd , trial are two parameters, when sd=trial=true, - // a new direction begins, when sd = false trial =true static bool sd = false; - - // a cubic interpolation is used to make the third point, - // when sa = trial = false, we use Brent to get the - // minimum point in this direction. - static bool trial = false; - - // ncggrad is a parameter to control the cg method, - // every ten cg direction, we change the direction back to - // the steepest descent method + static bool trial = false; static int ncggrad = 0; - static double fa = 0.0; static double fb = 0.0; static double fc = 0.0; - static double xa = 0.0; static double xb = 0.0; static double xc = 0.0; - static double xpt = 0.0; static double steplength = 0.0; static double fmax = 0.0; - static int nbrent = 0; - double *lat = new double[dim]; - double *grad = new double[dim]; - double *cg_gradn = new double[dim]; - double *move = new double[dim]; - double *cg_grad = new double[dim]; - + std::vector lat(dim, 0.0); + std::vector grad(dim, 0.0); + std::vector cg_gradn(dim, 0.0); + std::vector move(dim, 0.0); + std::vector cg_grad(dim, 0.0); double best_x = 0.0; double fmin = 0.0; - int flag = 0; - ModuleBase::GlobalFunc::ZEROS(lat, dim); - ModuleBase::GlobalFunc::ZEROS(grad, dim); - ModuleBase::GlobalFunc::ZEROS(cg_gradn, dim); - ModuleBase::GlobalFunc::ZEROS(move, dim); - ModuleBase::GlobalFunc::ZEROS(cg_grad, dim); - -CG_begin: - - if (Lattice_Change_Basic::stress_step == 1) + while (true) { - steplength = Lattice_Change_Basic::lattice_change_ini; // read in the init trust radius - // cout<<"Lattice_Change_Basic::lattice_change_ini = "< 6 * xb || best_x < (-xb)) - { - best_x = 6 * xb; - } - - setup_move(move, cg_gradn, best_x); - Lattice_Change_Basic::change_lattice(ucell, move, lat); - - trial = false; - xa = 0; - f_cal(move0.data(), move, dim, xc); - xc = xb + xc; - xpt = xc; - - Lattice_Change_Basic::lattice_change_ini = xc; + sd = true; + trial = true; + steplength = xb; + flag = 1; + continue; } - else + + CG_Base::normalize(dim, cg_gradn.data(), cg_grad0.data()); + CG_Base::third_order(e0, e1, fa, fb, xb, best_x); + + if (best_x > 6 * xb || best_x < (-xb)) { - double xtemp, ftemp; - f_cal(move0.data(), grad, dim, fc); - - fmin = std::abs(fc); - nbrent++; - // cout<<"nbrent = "< 0); - double gamma = 0.0; - double cg0_cg, cg0_cg0, cg0_g; - - if (ncggrad % 10000 == 0 || flag == 2) - { - for (int i = 0; i < dim; i++) - { - cg_grad[i] = grad[i]; - } - } - else - { - double gp_gp = 0.0; // grad_p.grad_p - double gg = 0.0; // grad.grad - double g_gp = 0.0; // grad_p.grad - double cgp_gp = 0.0; // cg_grad_p.grad_p - double cgp_g = 0.0; // cg_grad_p.grad - for (int i = 0; i < dim; i++) - { - gp_gp += grad0[i] * grad0[i]; - gg += grad[i] * grad[i]; - g_gp += grad0[i] * grad[i]; - cgp_gp += cg_grad0[i] * grad0[i]; - cgp_g += cg_grad0[i] * grad[i]; + Lattice_Change_Basic::lattice_change_ini = xc; + break; } - assert(g_gp != 0.0); - const double gamma1 = gg / gp_gp; // FR - // const double gamma2 = -(gg - g_gp)/(cgp_g - cgp_gp); //CW - const double gamma2 = (gg - g_gp) / gp_gp; // PRP - // const double gamma = gg/cgp_gp; //D - // const double gamma = -gg/(cgp_g - cgp_gp); //D-Y + double xtemp = 0.0; + double ftemp = 0.0; + CG_Base::f_cal(dim, move0.data(), grad.data(), fc); - if (gamma1 < 0.5) - { - gamma = gamma1; - } - else - { - gamma = gamma2; - } + fmin = std::abs(fc); + nbrent++; - for (int i = 0; i < dim; i++) + if ((fmin < std::abs((fmax) / 10.0)) || (nbrent > 3)) { - // we can consider step as modified gradient. - cg_grad[i] = grad[i] + gamma * cg_grad0[i]; + nbrent = 0; + sd = true; + trial = true; + steplength = xpt; + flag = 1; + continue; } - } - return; -} - -void Lattice_Change_CG::third_order(const double &e0, - const double &e1, - const double &fa, - const double &fb, - const double x, - double &best_x) -{ - double k3, k2, k1; - double dmoveh, dmove1, dmove2, dmove, ecal1, ecal2; - k3 = 3 * ((fb + fa) * x - 2 * (e1 - e0)) / (x * x * x); - k2 = (fb - fa) / x - k3 * x; - k1 = fa; - - dmoveh = x * fb / (fa - fb); - dmove1 = -k2 * (1 - sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); - dmove2 = -k2 * (1 + sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); - - if ((std::abs(k3 / k1) < 0.01) || ((k1 * k3 / (k2 * k2)) >= 0.25)) // this condition may be wrong - { - dmove = dmoveh; - } - else - { - dmove1 = -k2 * (1 - sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); - dmove2 = -k2 * (1 + sqrt(1 - 4 * k1 * k3 / (k2 * k2))) / (2 * k3); - ecal1 = k3 * dmove1 * dmove1 * dmove1 / 3 + k2 * dmove1 * dmove1 / 2 + k1 * dmove1; - ecal2 = k3 * dmove2 * dmove2 * dmove2 / 3 + k2 * dmove2 * dmove2 / 2 + k1 * dmove2; - if (ecal2 > ecal1) - dmove = dmove1 - x; - else - dmove = dmove2 - x; - - if (k3 < 0) - dmove = dmoveh; - } - - best_x = dmove; - return; -} - -void Lattice_Change_CG::Brent(double &fa, - double &fb, - double &fc, - double &xa, - double &xb, - double &xc, - double &best_x, - double &xpt) -{ - double dmove; - double tmp; - double k2, k1, k0; - double xnew1, xnew2; - double ecalnew1, ecalnew2; - - if ((fa * fb) > 0) - { - dmove = (xc * fa - xa * fc) / (fa - fc); - if (dmove > 4 * xc) - // if(dmove > 4 * xc || dmove < 0) - { - dmove = 4 * xc; - } - xb = xc; - fb = fc; - } - else - { - k2 = -((fb - fc) / (xb - xc) - (fa - fc) / (xa - xc)) / (xa - xb); - k1 = (fa - fc) / (xa - xc) - k2 * (xa + xc); - k0 = fa - k1 * xa - k2 * xa * xa; - xnew1 = (-k1 - sqrt(k1 * k1 - 4 * k2 * k0)) / (2 * k2); - xnew2 = (-k1 + sqrt(k1 * k1 - 4 * k2 * k0)) / (2 * k2); - - if (xnew1 > xnew2) + CG_Base::Brent(fa, fb, fc, xa, xb, xc, best_x, xpt); + if (xc < 0) { - tmp = xnew2; - xnew2 = xnew1; - xnew1 = tmp; + sd = true; + trial = true; + steplength = xb; + flag = 2; + continue; } - ecalnew1 = k2 * xnew1 * xnew1 * xnew1 / 3 + k1 * xnew1 * xnew1 / 2 + k0 * xnew1; - ecalnew2 = k2 * xnew2 * xnew2 * xnew2 / 3 + k1 * xnew2 * xnew2 / 2 + k0 * xnew2; - dmove = xnew1; + CG_Base::normalize(dim, cg_gradn.data(), cg_grad0.data()); + CG_Base::setup_move(dim, move.data(), cg_gradn.data(), best_x); + Lattice_Change_Basic::change_lattice(ucell, move.data(), lat.data()); - if (ecalnew1 > ecalnew2) - { - dmove = xnew2; - } - if (dmove < 0) - { - dmove = 2 * xc; // pengfei 14-6-5 - } - if (fa * fc > 0) - { - xa = xc; - fa = fc; - } - if (fb * fc > 0) - { - xb = xc; - fb = fc; - } + Lattice_Change_Basic::lattice_change_ini = xc; + break; } - best_x = dmove - xpt; - xpt = dmove; - xc = dmove; - return; -} - -void Lattice_Change_CG::f_cal(const double *g0, const double *g1, const int &dim, double &f_value) -{ - double hv0, hel; - hel = 0; - hv0 = 0; - for (int i = 0; i < dim; i++) - { - hel += g0[i] * g1[i]; - } - for (int i = 0; i < dim; i++) - { - hv0 += g0[i] * g0[i]; - } - - f_value = hel / sqrt(hv0); - return; -} - -void Lattice_Change_CG::setup_move(double *move, double *cg_gradn, const double &trust_radius) -{ - // movement using gradient and trust_radius. - for (int i = 0; i < dim; ++i) - { - move[i] = -cg_gradn[i] * trust_radius; - } - return; -} - -void Lattice_Change_CG::normalize(double *cg_gradn, const double *cg_grad, int dim) -{ - double norm = 0.0; - for (int i = 0; i < dim; ++i) - { - norm += pow(cg_grad[i], 2); - } - norm = sqrt(norm); - - if (norm != 0.0) - { - for (int i = 0; i < dim; ++i) - { - cg_gradn[i] = cg_grad[i] / norm; - } - } - return; -} +} \ No newline at end of file diff --git a/source/source_relax/lattice_change_cg.h b/source/source_relax/lattice_change_cg.h index 76d8dc70f8d..a2302cb26d9 100644 --- a/source/source_relax/lattice_change_cg.h +++ b/source/source_relax/lattice_change_cg.h @@ -3,8 +3,10 @@ #include "source_base/matrix.h" #include "source_cell/unitcell.h" +#include "cg_base.h" #include -class Lattice_Change_CG + +class Lattice_Change_CG : public CG_Base { public: @@ -19,30 +21,7 @@ class Lattice_Change_CG std::vector grad0; std::vector cg_grad0; std::vector move0; - double e0=0.0; - - // setup gradients. - void setup_cg_grad(double *grad, - const double *grad0, - double *cg_grad, - const double *cg_grad0, - const int &ncggrad, - int &flag); - - void setup_move(double *move, double *cg_gradn, const double &trust_radius); - - void Brent(double &fa, double &fb, double &fc, double &xa, double &xb, double &xc, double &best_x, double &xpt); - - void f_cal(const double *g0, const double *g1, const int &dim, double &f_value); - - void third_order(const double &e0, - const double &e1, - const double &fa, - const double &fb, - const double x, - double &best_x); - - void normalize(double *cg_gradn, const double *cg_grad, int dim); + double e0 = 0.0; }; -#endif +#endif \ No newline at end of file From e5fc0a9c5e2a2dc400f87b77d3e6f601c63beb86 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Tue, 9 Jun 2026 20:01:59 +0800 Subject: [PATCH 13/50] fix --- source/source_relax/test/lattice_change_methods_test.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/source/source_relax/test/lattice_change_methods_test.cpp b/source/source_relax/test/lattice_change_methods_test.cpp index 64173e110e1..dfc7fbddb5f 100644 --- a/source/source_relax/test/lattice_change_methods_test.cpp +++ b/source/source_relax/test/lattice_change_methods_test.cpp @@ -20,10 +20,6 @@ Lattice_Change_CG::Lattice_Change_CG() { } -Lattice_Change_CG::~Lattice_Change_CG() -{ -} - void Lattice_Change_CG::allocate(void) { } From 95c3ca7a6791bc2ad47f9b9e740d08cbec476f41 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Tue, 9 Jun 2026 20:55:22 +0800 Subject: [PATCH 14/50] fix test of relax module --- source/source_relax/cg_base.h | 40 +++++++------- source/source_relax/test/CMakeLists.txt | 21 +++++--- source/source_relax/test/bfgs_basic_test.cpp | 54 +++---------------- source/source_relax/test/bfgs_test.cpp | 1 + .../test/ions_move_basic_test.cpp | 12 +---- .../source_relax/test/ions_move_bfgs_test.cpp | 9 +--- .../source_relax/test/ions_move_cg_test.cpp | 36 +++++-------- .../source_relax/test/ions_move_sd_test.cpp | 14 ++--- .../test/lattice_change_basic_test.cpp | 10 +--- .../test/lattice_change_cg_test.cpp | 36 +++++-------- 10 files changed, 77 insertions(+), 156 deletions(-) diff --git a/source/source_relax/cg_base.h b/source/source_relax/cg_base.h index ce245830ce4..e2a3d929121 100644 --- a/source/source_relax/cg_base.h +++ b/source/source_relax/cg_base.h @@ -10,7 +10,7 @@ * The functions are designed to be independent of specific data sources. */ class CG_Base { -protected: +public: /** * @brief Setup conjugate gradient direction. * @param dim Dimension of the optimization problem @@ -25,15 +25,6 @@ class CG_Base { double *cg_grad, const double *cg_grad0, const int &ncggrad, int &flag); - /** - * @brief Calculate movement vector from CG direction. - * @param dim Dimension of the optimization problem - * @param move Output movement vector - * @param cg_gradn Normalized CG direction - * @param trust_radius Step size limit - */ - void setup_move(const int dim, double *move, double *cg_gradn, const double &trust_radius); - /** * @brief Brent's method for one-dimensional minimization. * @param fa Function value at xa @@ -49,15 +40,6 @@ class CG_Base { double &xa, double &xb, double &xc, double &best_x, double &xpt); - /** - * @brief Calculate projection of gradient onto search direction. - * @param dim Dimension of vectors - * @param g0 First vector (usually search direction) - * @param g1 Second vector (usually gradient) - * @param f_value Output projection value - */ - void f_cal(const int dim, const double *g0, const double *g1, double &f_value); - /** * @brief Third-order polynomial interpolation for line search. * @param e0 Energy at previous step @@ -71,6 +53,26 @@ class CG_Base { const double &fa, const double &fb, const double x, double &best_x); + /** + * @brief Calculate projection of gradient onto search direction. + * @param dim Dimension of vectors + * @param g0 First vector (usually search direction) + * @param g1 Second vector (usually gradient) + * @param f_value Output projection value + */ + void f_cal(const int dim, const double *g0, const double *g1, double &f_value); + + /** + * @brief Calculate movement vector from CG direction. + * @param dim Dimension of the optimization problem + * @param move Output movement vector + * @param cg_gradn Normalized CG direction + * @param trust_radius Step size limit + */ + void setup_move(const int dim, double *move, double *cg_gradn, const double &trust_radius); + +protected: + /** * @brief Normalize vector. * @param dim Dimension of vector diff --git a/source/source_relax/test/CMakeLists.txt b/source/source_relax/test/CMakeLists.txt index 2c19c41ff48..95b38fe3ba8 100644 --- a/source/source_relax/test/CMakeLists.txt +++ b/source/source_relax/test/CMakeLists.txt @@ -32,13 +32,13 @@ list(APPEND cell_source_files AddTest( TARGET MODULE_RELAX_lattice_change_methods_test LIBS parameter ${math_libs} base device - SOURCES lattice_change_methods_test.cpp ../lattice_change_methods.cpp ../lattice_change_basic.cpp mock_remake_cell.cpp + SOURCES lattice_change_methods_test.cpp ../lattice_change_methods.cpp ../lattice_change_basic.cpp ../relax_data.cpp mock_remake_cell.cpp ) AddTest( TARGET MODULE_RELAX_lattice_change_basic_test LIBS parameter ${math_libs} base device - SOURCES lattice_change_basic_test.cpp ../lattice_change_basic.cpp mock_remake_cell.cpp + SOURCES lattice_change_basic_test.cpp ../lattice_change_basic.cpp ../relax_data.cpp mock_remake_cell.cpp ) AddTest( @@ -47,27 +47,31 @@ AddTest( SOURCES lattice_change_cg_test.cpp ../lattice_change_cg.cpp ../lattice_change_basic.cpp + ../cg_base.cpp + ../relax_data.cpp mock_remake_cell.cpp ../../source_io/module_output/orb_io.cpp ) AddTest( TARGET MODULE_RELAX_bfgs_basic_test - LIBS parameter ${math_libs} base device - SOURCES bfgs_basic_test.cpp ../bfgs_basic.cpp + LIBS parameter ${math_libs} base device symmetry + SOURCES bfgs_basic_test.cpp ../bfgs_basic.cpp ../relax_data.cpp ../ions_move_basic.cpp + ../../source_io/module_output/orb_io.cpp + ${cell_source_files} ) AddTest( TARGET MODULE_RELAX_bfgs_test LIBS parameter ${math_libs} base device - SOURCES bfgs_test.cpp ../ions_move_bfgs2.cpp ../ions_move_basic.cpp ../matrix_methods.cpp ${cell_source_files} + SOURCES bfgs_test.cpp ../ions_move_bfgs2.cpp ../ions_move_basic.cpp ../matrix_methods.cpp ../relax_data.cpp ${cell_source_files} ) AddTest( TARGET MODULE_RELAX_ions_move_basic_test LIBS parameter ${math_libs} base device - SOURCES ions_move_basic_test.cpp ../ions_move_basic.cpp ${cell_source_files} + SOURCES ions_move_basic_test.cpp ../ions_move_basic.cpp ../relax_data.cpp ${cell_source_files} ) AddTest( @@ -77,6 +81,7 @@ AddTest( ../ions_move_bfgs.cpp ../ions_move_basic.cpp ../bfgs_basic.cpp + ../relax_data.cpp ../../source_io/module_output/orb_io.cpp ${cell_source_files} ) @@ -86,7 +91,9 @@ AddTest( LIBS parameter ${math_libs} base device SOURCES ions_move_cg_test.cpp ../ions_move_cg.cpp + ../cg_base.cpp ../ions_move_basic.cpp + ../relax_data.cpp ../../source_io/module_output/orb_io.cpp ${cell_source_files} ) @@ -94,5 +101,5 @@ AddTest( AddTest( TARGET MODULE_RELAX_ions_move_sd_test LIBS parameter ${math_libs} base device - SOURCES ions_move_sd_test.cpp ../ions_move_sd.cpp ../ions_move_basic.cpp ${cell_source_files} + SOURCES ions_move_sd_test.cpp ../ions_move_sd.cpp ../ions_move_basic.cpp ../relax_data.cpp ${cell_source_files} ) \ No newline at end of file diff --git a/source/source_relax/test/bfgs_basic_test.cpp b/source/source_relax/test/bfgs_basic_test.cpp index 91c028ec310..efd30e9829e 100644 --- a/source/source_relax/test/bfgs_basic_test.cpp +++ b/source/source_relax/test/bfgs_basic_test.cpp @@ -1,4 +1,5 @@ #include "source_relax/ions_move_basic.h" +#include "source_relax/relax_data.h" #include "gmock/gmock.h" #define private public #include "source_io/module_parameter/parameter.h" @@ -13,44 +14,6 @@ * unit tests of class BFGS_Basic ***********************************************/ -/** - * - Tested Functions: - * - BFGS_Basic::allocate_basic() - * - BFGS_Basic::new_step() - * - BFGS_Basic::reset_hessian() - * - BFGS_Basic::save_bfgs() - * - BFGS_Basic::check_move() - * - BFGS_Basic::update_inverse_hessian() - * - BFGS_Basic::check_wolfe_conditions() - * - BFGS_Basic::compute_trust_radius() - */ - -int Ions_Move_Basic::dim = 0; -bool Ions_Move_Basic::converged = false; -double Ions_Move_Basic::largest_grad = 0.0; -int Ions_Move_Basic::update_iter = 0; -int Ions_Move_Basic::istep = 0; -double Ions_Move_Basic::ediff = 0.0; -double Ions_Move_Basic::etot = 0.0; -double Ions_Move_Basic::etot_p = 0.0; -double Ions_Move_Basic::trust_radius = 0.0; -double Ions_Move_Basic::trust_radius_old = 0.0; -double Ions_Move_Basic::relax_bfgs_rmax = -1.0; -double Ions_Move_Basic::relax_bfgs_rmin = -1.0; -double Ions_Move_Basic::relax_bfgs_init = -1.0; -double Ions_Move_Basic::best_xxx = 1.0; -int Ions_Move_Basic::out_stru = 0; - -double Ions_Move_Basic::dot_func(const double *a, const double *b, const int &dim_in) -{ - double result = 0.0; - for (int i = 0; i < dim_in; i++) - { - result += a[i] * b[i]; - } - return result; -} - class BFGSBasicTest : public ::testing::Test { protected: @@ -73,14 +36,13 @@ TEST_F(BFGSBasicTest, TestAllocate) Ions_Move_Basic::dim = 4; bfgs.allocate_basic(); - // Check if allocated arrays are not empty - EXPECT_NE(nullptr, bfgs.pos); - EXPECT_NE(nullptr, bfgs.pos_p); - EXPECT_NE(nullptr, bfgs.grad); - EXPECT_NE(nullptr, bfgs.grad_p); - EXPECT_NE(nullptr, bfgs.move); - EXPECT_NE(nullptr, bfgs.move_p); - EXPECT_NE(nullptr, bfgs.inv_hess.c); + // Check if allocated vectors are not empty + EXPECT_EQ(bfgs.pos.size(), 4U); + EXPECT_EQ(bfgs.pos_p.size(), 4U); + EXPECT_EQ(bfgs.grad.size(), 4U); + EXPECT_EQ(bfgs.grad_p.size(), 4U); + EXPECT_EQ(bfgs.move.size(), 4U); + EXPECT_EQ(bfgs.move_p.size(), 4U); } // Test if a dimension less than or equal to 0 results in an assertion error diff --git a/source/source_relax/test/bfgs_test.cpp b/source/source_relax/test/bfgs_test.cpp index 81852def15f..081012dba39 100644 --- a/source/source_relax/test/bfgs_test.cpp +++ b/source/source_relax/test/bfgs_test.cpp @@ -12,6 +12,7 @@ #undef private #include "source_relax/ions_move_basic.h" // for Ions_Move_Basic static members +#include "source_relax/relax_data.h" /************************************************ * unit tests for Ions_Move_BFGS2 (no MockUnitCell) diff --git a/source/source_relax/test/ions_move_basic_test.cpp b/source/source_relax/test/ions_move_basic_test.cpp index d9e9caaf338..b6f02628aec 100644 --- a/source/source_relax/test/ions_move_basic_test.cpp +++ b/source/source_relax/test/ions_move_basic_test.cpp @@ -4,23 +4,13 @@ #include "source_io/module_parameter/parameter.h" #undef private #include "source_relax/ions_move_basic.h" +#include "source_relax/relax_data.h" #include "for_test.h" /************************************************ * unit tests of namespace Ions_Move_Basic ***********************************************/ -/** - * - Tested Functions: - * - Ions_Move_Basic::setup_gradient() - * - Ions_Move_Basic::move_atoms() - * - Ions_Move_Basic::check_converged() - * - Ions_Move_Basic::terminate() - * - Ions_Move_Basic::setup_etot() - * - Ions_Move_Basic::dot_func() - * - Ions_Move_Basic::third_order() - */ - // Define a fixture for the tests class IonsMoveBasicTest : public ::testing::Test { diff --git a/source/source_relax/test/ions_move_bfgs_test.cpp b/source/source_relax/test/ions_move_bfgs_test.cpp index bbf9bfadf93..f13ef8c3ea5 100644 --- a/source/source_relax/test/ions_move_bfgs_test.cpp +++ b/source/source_relax/test/ions_move_bfgs_test.cpp @@ -8,18 +8,11 @@ #include "source_relax/ions_move_bfgs.h" #undef private #undef protected + /************************************************ * unit tests of class Ions_Move_BFGS ***********************************************/ -/** - * - Tested Functions: - * - Ions_Move_BFGS::allocate() - * - Ions_Move_BFGS::start() - * - Ions_Move_BFGS::bfgs_routine() - * - Ions_Move_BFGS::restart_bfgs() - */ - // Define a fixture for the tests class IonsMoveBFGSTest : public ::testing::Test { diff --git a/source/source_relax/test/ions_move_cg_test.cpp b/source/source_relax/test/ions_move_cg_test.cpp index c0aa34dceca..83c4323be11 100644 --- a/source/source_relax/test/ions_move_cg_test.cpp +++ b/source/source_relax/test/ions_move_cg_test.cpp @@ -7,21 +7,11 @@ #include "source_relax/ions_move_basic.h" #include "source_relax/ions_move_cg.h" #undef private + /************************************************ * unit tests of class Ions_Move_CG ***********************************************/ -/** - * - Tested Functions: - * - Ions_Move_CG::allocate() - * - Ions_Move_CG::start() - * - Ions_Move_CG::setup_cg_grad() - * - Ions_Move_CG::setup_move() - * - Ions_Move_CG::Brent() - * - Ions_Move_CG::f_cal() - * - Ions_Move_CG::third_order() - */ - class IonsMoveCGTest : public ::testing::Test { protected: @@ -70,11 +60,11 @@ TEST_F(IonsMoveCGTest, TestAllocate) Ions_Move_Basic::dim = 4; im_cg.allocate(); - // Check if allocated arrays are not empty - EXPECT_NE(nullptr, im_cg.pos0); - EXPECT_NE(nullptr, im_cg.grad0); - EXPECT_NE(nullptr, im_cg.cg_grad0); - EXPECT_NE(nullptr, im_cg.move0); + // Check if allocated vectors are not empty + EXPECT_EQ(im_cg.pos0.size(), 4U); + EXPECT_EQ(im_cg.grad0.size(), 4U); + EXPECT_EQ(im_cg.cg_grad0.size(), 4U); + EXPECT_EQ(im_cg.move0.size(), 4U); } // Test if a dimension less than or equal to 0 results in an assertion error @@ -374,7 +364,7 @@ TEST_F(IonsMoveCGTest, SetupCgGradNcggradIsMultipleOf10000) int ncggrad = 50000; // multiple of 10000 int flag = 0; - im_cg.setup_cg_grad(grad, grad0, cggrad, cggrad0, ncggrad, flag); + im_cg.setup_cg_grad(Ions_Move_Basic::dim, grad, grad0, cggrad, cggrad0, ncggrad, flag); EXPECT_DOUBLE_EQ(cggrad[0], grad[0]); EXPECT_DOUBLE_EQ(cggrad[1], grad[1]); @@ -394,7 +384,7 @@ TEST_F(IonsMoveCGTest, SetupCgGradNcggradIsNotMultipleOf10000Case1) int ncggrad = 100; int flag = 0; - im_cg.setup_cg_grad(grad, grad0, cggrad, cggrad0, ncggrad, flag); + im_cg.setup_cg_grad(Ions_Move_Basic::dim, grad, grad0, cggrad, cggrad0, ncggrad, flag); EXPECT_DOUBLE_EQ(cggrad[0], 1.25); EXPECT_DOUBLE_EQ(cggrad[1], 0.0); @@ -414,7 +404,7 @@ TEST_F(IonsMoveCGTest, SetupCgGradNcggradIsNotMultipleOf10000Case2) int ncggrad = 100; int flag = 0; - im_cg.setup_cg_grad(grad, grad0, cggrad, cggrad0, ncggrad, flag); + im_cg.setup_cg_grad(Ions_Move_Basic::dim, grad, grad0, cggrad, cggrad0, ncggrad, flag); EXPECT_DOUBLE_EQ(cggrad[0], grad[0]); EXPECT_DOUBLE_EQ(cggrad[1], grad[1]); @@ -571,9 +561,9 @@ TEST_F(IonsMoveCGTest, Fcal) Ions_Move_Basic::dim = 9; double g0[9] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; double g1[9] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; - double f_value; + double f_value = 0.0; - im_cg.f_cal(g0, g1, Ions_Move_Basic::dim, f_value); + im_cg.f_cal(Ions_Move_Basic::dim, g0, g1, f_value); EXPECT_DOUBLE_EQ(f_value, 3.0); } @@ -584,9 +574,9 @@ TEST_F(IonsMoveCGTest, SetupMove) Ions_Move_Basic::dim = 9; double trust_radius = 1.0; double cg_gradn[9] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; - double move[9]; + double move[9] = {0.0}; - im_cg.setup_move(move, cg_gradn, trust_radius); + im_cg.setup_move(Ions_Move_Basic::dim, move, cg_gradn, trust_radius); EXPECT_DOUBLE_EQ(move[0], -1.0); EXPECT_DOUBLE_EQ(move[1], -1.0); diff --git a/source/source_relax/test/ions_move_sd_test.cpp b/source/source_relax/test/ions_move_sd_test.cpp index 26d5afe2332..647247ecd38 100644 --- a/source/source_relax/test/ions_move_sd_test.cpp +++ b/source/source_relax/test/ions_move_sd_test.cpp @@ -7,17 +7,11 @@ #include "source_relax/ions_move_basic.h" #include "source_relax/ions_move_sd.h" #undef private + /************************************************ * unit tests of class Ions_Move_SD ***********************************************/ -/** - * - Tested Functions: - * - Ions_Move_SD::allocate() - * - Ions_Move_SD::start() - * - Ions_Move_SD::cal_tradius_sd() - */ - class IonsMoveSDTest : public ::testing::Test { protected: @@ -44,9 +38,9 @@ TEST_F(IonsMoveSDTest, TestAllocate) Ions_Move_Basic::dim = 4; im_sd.allocate(); - // Check if allocated arrays are not empty - EXPECT_NE(nullptr, im_sd.grad_saved); - EXPECT_NE(nullptr, im_sd.pos_saved); + // Check if allocated vectors are not empty + EXPECT_EQ(im_sd.grad_saved.size(), 4U); + EXPECT_EQ(im_sd.pos_saved.size(), 4U); } // Test if a dimension less than or equal to 0 results in an assertion error diff --git a/source/source_relax/test/lattice_change_basic_test.cpp b/source/source_relax/test/lattice_change_basic_test.cpp index b40af6d88a9..2742d39f5b9 100644 --- a/source/source_relax/test/lattice_change_basic_test.cpp +++ b/source/source_relax/test/lattice_change_basic_test.cpp @@ -1,4 +1,5 @@ #include "source_relax/lattice_change_basic.h" +#include "source_relax/relax_data.h" #include "mock_remake_cell.h" #include "for_test.h" @@ -12,15 +13,6 @@ * unit tests of namespace Lattice_Change_Basic ***********************************************/ -/** - * - Tested Functions: - * - Lattice_Change_Basic::setup_gradient() - * - Lattice_Change_Basic::change_lattice() - * - Lattice_Change_Basic::check_converged() - * - Lattice_Change_Basic::terminate() - * - Lattice_Change_Basic::setup_etot() - */ - // Define a fixture for the tests class LatticeChangeBasicTest : public ::testing::Test { diff --git a/source/source_relax/test/lattice_change_cg_test.cpp b/source/source_relax/test/lattice_change_cg_test.cpp index 01c863b8eed..11a320d3712 100644 --- a/source/source_relax/test/lattice_change_cg_test.cpp +++ b/source/source_relax/test/lattice_change_cg_test.cpp @@ -5,21 +5,11 @@ #include "source_relax/lattice_change_basic.h" #include "source_relax/lattice_change_cg.h" #undef private + /************************************************ * unit tests of class Lattice_Change_CG ***********************************************/ -/** - * - Tested Functions: - * - Lattice_Change_CG::allocate() - * - Lattice_Change_CG::start() - * - Lattice_Change_CG::setup_cg_grad() - * - Lattice_Change_CG::setup_move() - * - Lattice_Change_CG::Brent() - * - Lattice_Change_CG::f_cal() - * - Lattice_Change_CG::third_order() - */ - class LatticeChangeCGTest : public ::testing::Test { protected: @@ -47,11 +37,11 @@ TEST_F(LatticeChangeCGTest, TestAllocate) Lattice_Change_Basic::dim = 4; lc_cg.allocate(); - // Check if allocated arrays are not empty - EXPECT_NE(nullptr, lc_cg.lat0); - EXPECT_NE(nullptr, lc_cg.grad0); - EXPECT_NE(nullptr, lc_cg.cg_grad0); - EXPECT_NE(nullptr, lc_cg.move0); + // Check if allocated vectors are not empty + EXPECT_EQ(lc_cg.lat0.size(), 4U); + EXPECT_EQ(lc_cg.grad0.size(), 4U); + EXPECT_EQ(lc_cg.cg_grad0.size(), 4U); + EXPECT_EQ(lc_cg.move0.size(), 4U); } // Test if a dimension less than or equal to 0 results in an assertion error @@ -300,7 +290,7 @@ TEST_F(LatticeChangeCGTest, SetupCgGradNcggradIsMultipleOf10000) int ncggrad = 50000; // multiple of 10000 int flag = 0; - lc_cg.setup_cg_grad(grad, grad0, cggrad, cggrad0, ncggrad, flag); + lc_cg.setup_cg_grad(Lattice_Change_Basic::dim, grad, grad0, cggrad, cggrad0, ncggrad, flag); EXPECT_DOUBLE_EQ(cggrad[0], grad[0]); EXPECT_DOUBLE_EQ(cggrad[1], grad[1]); @@ -323,7 +313,7 @@ TEST_F(LatticeChangeCGTest, SetupCgGradNcggradIsNotMultipleOf10000Case1) int ncggrad = 100; int flag = 0; - lc_cg.setup_cg_grad(grad, grad0, cggrad, cggrad0, ncggrad, flag); + lc_cg.setup_cg_grad(Lattice_Change_Basic::dim, grad, grad0, cggrad, cggrad0, ncggrad, flag); EXPECT_DOUBLE_EQ(cggrad[0], 1.25); EXPECT_DOUBLE_EQ(cggrad[1], 0.0); @@ -346,7 +336,7 @@ TEST_F(LatticeChangeCGTest, SetupCgGradNcggradIsNotMultipleOf10000Case2) int ncggrad = 100; int flag = 0; - lc_cg.setup_cg_grad(grad, grad0, cggrad, cggrad0, ncggrad, flag); + lc_cg.setup_cg_grad(Lattice_Change_Basic::dim, grad, grad0, cggrad, cggrad0, ncggrad, flag); EXPECT_DOUBLE_EQ(cggrad[0], grad[0]); EXPECT_DOUBLE_EQ(cggrad[1], grad[1]); @@ -506,9 +496,9 @@ TEST_F(LatticeChangeCGTest, Fcal) Lattice_Change_Basic::dim = 9; double g0[9] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; double g1[9] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; - double f_value; + double f_value = 0.0; - lc_cg.f_cal(g0, g1, Lattice_Change_Basic::dim, f_value); + lc_cg.f_cal(Lattice_Change_Basic::dim, g0, g1, f_value); EXPECT_DOUBLE_EQ(f_value, 3.0); } @@ -519,9 +509,9 @@ TEST_F(LatticeChangeCGTest, SetupMove) Lattice_Change_Basic::dim = 9; double trust_radius = 1.0; double cg_gradn[9] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; - double move[9]; + double move[9] = {0.0}; - lc_cg.setup_move(move, cg_gradn, trust_radius); + lc_cg.setup_move(Lattice_Change_Basic::dim, move, cg_gradn, trust_radius); EXPECT_DOUBLE_EQ(move[0], -1.0); EXPECT_DOUBLE_EQ(move[1], -1.0); From 18fbff9907953337efa4e8692dd27f50845baf92 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Tue, 9 Jun 2026 21:07:31 +0800 Subject: [PATCH 15/50] remove ZEROS function --- source/source_relax/bfgs_basic.cpp | 16 ++++++---------- source/source_relax/ions_move_basic.cpp | 5 +++-- source/source_relax/ions_move_bfgs.cpp | 7 ++++--- source/source_relax/ions_move_sd.cpp | 10 ++++------ 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/source/source_relax/bfgs_basic.cpp b/source/source_relax/bfgs_basic.cpp index f542d209a30..36fc12f0a15 100644 --- a/source/source_relax/bfgs_basic.cpp +++ b/source/source_relax/bfgs_basic.cpp @@ -1,4 +1,5 @@ #include "bfgs_basic.h" +#include #include "source_io/module_parameter/parameter.h" #include "ions_move_basic.h" #include "source_base/global_function.h" @@ -36,10 +37,8 @@ void BFGS_Basic::update_inverse_hessian(const double &lat0) // ModuleBase::TITLE("Ions_Move_BFGS","update_inverse_hessian"); assert(dim > 0); - std::vector s(dim); - std::vector y(dim); - ModuleBase::GlobalFunc::ZEROS(s.data(), dim); - ModuleBase::GlobalFunc::ZEROS(y.data(), dim); + std::vector s(dim, 0.0); + std::vector y(dim, 0.0); for (int i = 0; i < dim; i++) { @@ -64,12 +63,9 @@ void BFGS_Basic::update_inverse_hessian(const double &lat0) return; } - std::vector Hs(dim); - std::vector Hy(dim); - std::vector yH(dim); - ModuleBase::GlobalFunc::ZEROS(Hs.data(), dim); - ModuleBase::GlobalFunc::ZEROS(Hy.data(), dim); - ModuleBase::GlobalFunc::ZEROS(yH.data(), dim); + std::vector Hs(dim, 0.0); + std::vector Hy(dim, 0.0); + std::vector yH(dim, 0.0); for (int i = 0; i < dim; i++) { diff --git a/source/source_relax/ions_move_basic.cpp b/source/source_relax/ions_move_basic.cpp index c2b3d0cd9c8..08b45d29ce8 100644 --- a/source/source_relax/ions_move_basic.cpp +++ b/source/source_relax/ions_move_basic.cpp @@ -1,5 +1,6 @@ #include "ions_move_basic.h" +#include #include "source_io/module_parameter/parameter.h" #include "source_base/global_function.h" #include "source_base/global_variable.h" @@ -26,8 +27,8 @@ void Ions_Move_Basic::setup_gradient(const UnitCell &ucell, const ModuleBase::ma assert(grad != nullptr); assert(dim == 3 * ucell.nat); - ModuleBase::GlobalFunc::ZEROS(pos, dim); - ModuleBase::GlobalFunc::ZEROS(grad, dim); + std::fill_n(pos, dim, 0.0); + std::fill_n(grad, dim, 0.0); // (1) init gradient // the unit of pos: Bohr. diff --git a/source/source_relax/ions_move_bfgs.cpp b/source/source_relax/ions_move_bfgs.cpp index 31c9f33f86d..11b712805ba 100644 --- a/source/source_relax/ions_move_bfgs.cpp +++ b/source/source_relax/ions_move_bfgs.cpp @@ -1,5 +1,6 @@ #include "ions_move_bfgs.h" +#include #include "source_io/module_parameter/parameter.h" #include "ions_move_basic.h" #include "source_base/global_function.h" @@ -130,9 +131,9 @@ void Ions_Move_BFGS::restart_bfgs(const double& lat0) else { // bfgs initialization - ModuleBase::GlobalFunc::ZEROS(pos_p.data(), dim); - ModuleBase::GlobalFunc::ZEROS(grad_p.data(), dim); - ModuleBase::GlobalFunc::ZEROS(move_p.data(), dim); + std::fill(pos_p.begin(), pos_p.end(), 0.0); + std::fill(grad_p.begin(), grad_p.end(), 0.0); + std::fill(move_p.begin(), move_p.end(), 0.0); Ions_Move_Basic::update_iter = 0; diff --git a/source/source_relax/ions_move_sd.cpp b/source/source_relax/ions_move_sd.cpp index 8302e509a46..2e0f4f7a322 100644 --- a/source/source_relax/ions_move_sd.cpp +++ b/source/source_relax/ions_move_sd.cpp @@ -1,5 +1,6 @@ #include "ions_move_sd.h" +#include #include "source_io/module_parameter/parameter.h" #include "ions_move_basic.h" #include "source_base/global_function.h" @@ -27,12 +28,9 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const assert(grad_saved.size() == static_cast(dim)); assert(pos_saved.size() == static_cast(dim)); - std::vector pos(dim); - std::vector grad(dim); - std::vector move(dim); - ModuleBase::GlobalFunc::ZEROS(pos.data(), dim); - ModuleBase::GlobalFunc::ZEROS(grad.data(), dim); - ModuleBase::GlobalFunc::ZEROS(move.data(), dim); + std::vector pos(dim, 0.0); + std::vector grad(dim, 0.0); + std::vector move(dim, 0.0); // 1: ediff = 0 // 0: ediff < 0 From fee96c227e0f0cd4a5be5b5ca5b1b79d28478f7f Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Tue, 9 Jun 2026 22:01:53 +0800 Subject: [PATCH 16/50] remove GlobalC, phase 1 --- source/source_relax/bfgs_basic.cpp | 63 +++++++------- source/source_relax/bfgs_basic.h | 10 ++- source/source_relax/ions_move_basic.cpp | 50 +++++------ source/source_relax/ions_move_basic.h | 14 +++- source/source_relax/ions_move_bfgs.cpp | 40 ++++----- source/source_relax/ions_move_bfgs.h | 8 +- source/source_relax/ions_move_cg.cpp | 14 ++-- source/source_relax/ions_move_cg.h | 4 +- source/source_relax/ions_move_methods.cpp | 11 +-- source/source_relax/ions_move_methods.h | 5 +- source/source_relax/ions_move_sd.cpp | 10 +-- source/source_relax/ions_move_sd.h | 4 +- source/source_relax/relax_nsync.cpp | 7 +- source/source_relax/relax_nsync.h | 4 +- source/source_relax/test/bfgs_basic_test.cpp | 49 +++++++---- .../test/ions_move_basic_test.cpp | 65 ++++++++------- .../source_relax/test/ions_move_bfgs_test.cpp | 78 ++++++++++-------- .../source_relax/test/ions_move_cg_test.cpp | 82 ++++++++++++------- .../source_relax/test/ions_move_sd_test.cpp | 20 ++--- 19 files changed, 306 insertions(+), 232 deletions(-) diff --git a/source/source_relax/bfgs_basic.cpp b/source/source_relax/bfgs_basic.cpp index 36fc12f0a15..54a8c889a1b 100644 --- a/source/source_relax/bfgs_basic.cpp +++ b/source/source_relax/bfgs_basic.cpp @@ -32,7 +32,7 @@ void BFGS_Basic::allocate_basic(void) return; } -void BFGS_Basic::update_inverse_hessian(const double &lat0) +void BFGS_Basic::update_inverse_hessian(const double &lat0, std::ofstream& ofs) { // ModuleBase::TITLE("Ions_Move_BFGS","update_inverse_hessian"); assert(dim > 0); @@ -57,8 +57,8 @@ void BFGS_Basic::update_inverse_hessian(const double &lat0) } if (std::abs(sdoty) < 1.0e-16) { - GlobalV::ofs_running << " WARINIG: unexpected behaviour in update_inverse_hessian" << std::endl; - GlobalV::ofs_running << " Resetting bfgs history " << std::endl; + ofs << " WARINIG: unexpected behaviour in update_inverse_hessian" << std::endl; + ofs << " Resetting bfgs history " << std::endl; this->reset_hessian(); return; } @@ -96,7 +96,7 @@ void BFGS_Basic::update_inverse_hessian(const double &lat0) return; } -void BFGS_Basic::check_wolfe_conditions(void) +void BFGS_Basic::check_wolfe_conditions(std::ofstream& ofs) { double dot_p = dot_func(grad_p.data(), move_p.data(), dim); double dot = dot_func(grad.data(), move_p.data(), dim); @@ -111,14 +111,14 @@ void BFGS_Basic::check_wolfe_conditions(void) if (PARAM.inp.test_relax_method) { - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "etot - etot_p", etot - etot_p); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "relax_bfgs_w1 * dot_p", relax_bfgs_w1 * dot_p); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "dot", dot); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "relax_bfgs_w2 * dot_p", relax_bfgs_w2 * dot_p); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "relax_bfgs_w1", relax_bfgs_w1); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "relax_bfgs_w2", relax_bfgs_w2); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wolfe1", wolfe1); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wolfe2", wolfe2); + ModuleBase::GlobalFunc::OUT(ofs, "etot - etot_p", etot - etot_p); + ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w1 * dot_p", relax_bfgs_w1 * dot_p); + ModuleBase::GlobalFunc::OUT(ofs, "dot", dot); + ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w2 * dot_p", relax_bfgs_w2 * dot_p); + ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w1", relax_bfgs_w1); + ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w2", relax_bfgs_w2); + ModuleBase::GlobalFunc::OUT(ofs, "wolfe1", wolfe1); + ModuleBase::GlobalFunc::OUT(ofs, "wolfe2", wolfe2); } this->wolfe_flag = wolfe1 && wolfe2; @@ -135,13 +135,13 @@ void BFGS_Basic::check_wolfe_conditions(void) } */ - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "etot - etot_p", etot - etot_p); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "relax_bfgs_w1 * dot_p", relax_bfgs_w1 * dot_p); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wolfe1", wolfe1); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wolfe2", wolfe2); + ModuleBase::GlobalFunc::OUT(ofs, "etot - etot_p", etot - etot_p); + ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w1 * dot_p", relax_bfgs_w1 * dot_p); + ModuleBase::GlobalFunc::OUT(ofs, "wolfe1", wolfe1); + ModuleBase::GlobalFunc::OUT(ofs, "wolfe2", wolfe2); // ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,"dot = ",dot); // ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running,"dot_p = ",dot_p); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wolfe condition satisfied", wolfe_flag); + ModuleBase::GlobalFunc::OUT(ofs, "wolfe condition satisfied", wolfe_flag); return; } @@ -175,7 +175,7 @@ void BFGS_Basic::save_bfgs(void) // a new bfgs step is done // we have already done well in the previous direction // we should get a new direction in this case -void BFGS_Basic::new_step(const double &lat0) +void BFGS_Basic::new_step(const double &lat0, std::ofstream& ofs) { ModuleBase::TITLE("BFGS_Basic", "new_step"); @@ -203,8 +203,8 @@ void BFGS_Basic::new_step(const double &lat0) } else if (Ions_Move_Basic::update_iter > 1) { - this->check_wolfe_conditions(); - this->update_inverse_hessian(lat0); + this->check_wolfe_conditions(ofs); + this->update_inverse_hessian(lat0, ofs); } //-------------------------------------------------------------------- @@ -227,7 +227,8 @@ void BFGS_Basic::new_step(const double &lat0) // std::cout << " move after hess " << move[i] << std::endl; } - GlobalV::ofs_running << " check the norm of new move " << dot_func(move.data(), move.data(), dim) << " (Bohr)" << std::endl; + + ofs << " check the norm of new move " << dot_func(move.data(), move.data(), dim) << " (Bohr)" << std::endl; } else if (bfgs_ndim > 1) { @@ -244,7 +245,7 @@ void BFGS_Basic::new_step(const double &lat0) if (dot > 0.0) { - GlobalV::ofs_running << " Uphill move : resetting bfgs history" << std::endl; + ofs << " Uphill move : resetting bfgs history" << std::endl; for (int i = 0; i < dim; i++) { move[i] = -grad[i]; @@ -264,7 +265,7 @@ void BFGS_Basic::new_step(const double &lat0) else if (Ions_Move_Basic::update_iter > 1) { trust_radius = trust_radius_old; - this->compute_trust_radius(); + this->compute_trust_radius(ofs); } // std::cout<<"trust_radius ="<<" "<move.data(), this->move.data(), dim); norm_move = std::sqrt(norm_move); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "move(norm)", norm_move); + ModuleBase::GlobalFunc::OUT(ofs, "move(norm)", norm_move); ltest = ltest && (norm_move > trust_radius_old); @@ -320,11 +321,11 @@ void BFGS_Basic::compute_trust_radius(void) if (PARAM.inp.test_relax_method) { - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wolfe_flag", wolfe_flag); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "trust_radius_old", trust_radius_old); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "2*a*trust_radius_old", 2.0 * a * trust_radius_old); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "norm_move", norm_move); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "Trust_radius (Bohr)", trust_radius); + ModuleBase::GlobalFunc::OUT(ofs, "wolfe_flag", wolfe_flag); + ModuleBase::GlobalFunc::OUT(ofs, "trust_radius_old", trust_radius_old); + ModuleBase::GlobalFunc::OUT(ofs, "2*a*trust_radius_old", 2.0 * a * trust_radius_old); + ModuleBase::GlobalFunc::OUT(ofs, "norm_move", norm_move); + ModuleBase::GlobalFunc::OUT(ofs, "Trust_radius (Bohr)", trust_radius); } if (trust_radius < relax_bfgs_rmin) @@ -336,7 +337,7 @@ void BFGS_Basic::compute_trust_radius(void) // something is going wrongsomething is going wrong ModuleBase::WARNING_QUIT("bfgs", "bfgs history already reset at previous step, we got trapped!"); } - GlobalV::ofs_running << " Resetting BFGS history." << std::endl; + ofs << " Resetting BFGS history." << std::endl; this->reset_hessian(); for (int i = 0; i < dim; i++) { diff --git a/source/source_relax/bfgs_basic.h b/source/source_relax/bfgs_basic.h index 6e74cac9cdd..8d101bce1e4 100644 --- a/source/source_relax/bfgs_basic.h +++ b/source/source_relax/bfgs_basic.h @@ -1,6 +1,8 @@ #ifndef BFGS_BASIC #define BFGS_BASIC +#include +#include #include "source_base/matrix.h" #include @@ -23,7 +25,7 @@ class BFGS_Basic protected: void allocate_basic(void); - void new_step(const double& lat0); + void new_step(const double& lat0, std::ofstream& ofs); void reset_hessian(void); void save_bfgs(void); @@ -53,9 +55,9 @@ class BFGS_Basic int bfgs_ndim; - void update_inverse_hessian(const double& lat0); - void check_wolfe_conditions(void); - void compute_trust_radius(void); + void update_inverse_hessian(const double& lat0, std::ofstream& ofs); + void check_wolfe_conditions(std::ofstream& ofs); + void compute_trust_radius(std::ofstream& ofs); }; #endif diff --git a/source/source_relax/ions_move_basic.cpp b/source/source_relax/ions_move_basic.cpp index 08b45d29ce8..03157644e56 100644 --- a/source/source_relax/ions_move_basic.cpp +++ b/source/source_relax/ions_move_basic.cpp @@ -18,7 +18,7 @@ double Ions_Move_Basic::best_xxx = 1.0; int Ions_Move_Basic::out_stru = 0; std::vector Ions_Move_Basic::relax_method = {"bfgs","2"}; -void Ions_Move_Basic::setup_gradient(const UnitCell &ucell, const ModuleBase::matrix &force, double *pos, double *grad) +void Ions_Move_Basic::setup_gradient(const UnitCell &ucell, const ModuleBase::matrix &force, double *pos, double *grad, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_Basic", "setup_gradient"); @@ -55,7 +55,7 @@ void Ions_Move_Basic::setup_gradient(const UnitCell &ucell, const ModuleBase::ma return; } -void Ions_Move_Basic::move_atoms(UnitCell &ucell, double *move, double *pos) +void Ions_Move_Basic::move_atoms(UnitCell &ucell, double *move, double *pos, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_Basic", "move_atoms"); @@ -68,8 +68,8 @@ void Ions_Move_Basic::move_atoms(UnitCell &ucell, double *move, double *pos) if (PARAM.inp.test_relax_method) { int iat = 0; - GlobalV::ofs_running << "\n movement of ions (unit is Bohr) : " << std::endl; - GlobalV::ofs_running << " " << std::setw(12) << "Atom" << std::setw(15) << "x" << std::setw(15) << "y" + ofs << "\n movement of ions (unit is Bohr) : " << std::endl; + ofs << " " << std::setw(12) << "Atom" << std::setw(15) << "x" << std::setw(15) << "y" << std::setw(15) << "z" << std::endl; for (int it = 0; it < ucell.ntype; it++) { @@ -77,7 +77,7 @@ void Ions_Move_Basic::move_atoms(UnitCell &ucell, double *move, double *pos) { std::stringstream ss; ss << "move_" << ucell.atoms[it].label << ia + 1; - GlobalV::ofs_running << " " << std::setw(12) << ss.str().c_str() << std::setw(15) << move[3 * iat + 0] + ofs << " " << std::setw(12) << ss.str().c_str() << std::setw(15) << move[3 * iat + 0] << std::setw(15) << move[3 * iat + 1] << std::setw(15) << move[3 * iat + 2] << std::endl; iat++; @@ -106,12 +106,12 @@ void Ions_Move_Basic::move_atoms(UnitCell &ucell, double *move, double *pos) //-------------------------------------------- // Print out the structure file. //-------------------------------------------- - unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,GlobalV::ofs_running); + unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,ofs); return; } -void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad) +void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_Basic", "check_converged"); assert(dim > 0); @@ -132,10 +132,10 @@ void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad) if (PARAM.inp.test_relax_method) { - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "old total energy (ry)", etot_p); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "new total energy (ry)", etot); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "energy difference (ry)", Ions_Move_Basic::ediff); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "largest gradient (ry/bohr)", Ions_Move_Basic::largest_grad); + ModuleBase::GlobalFunc::OUT(ofs, "old total energy (ry)", etot_p); + ModuleBase::GlobalFunc::OUT(ofs, "new total energy (ry)", etot); + ModuleBase::GlobalFunc::OUT(ofs, "energy difference (ry)", Ions_Move_Basic::ediff); + ModuleBase::GlobalFunc::OUT(ofs, "largest gradient (ry/bohr)", Ions_Move_Basic::largest_grad); } if (PARAM.inp.out_level == "ie") @@ -144,7 +144,7 @@ void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad) std::cout << " LARGEST GRAD (eV/Angstrom) : " << Ions_Move_Basic::largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A << std::endl; - GlobalV::ofs_running << "\n Largest force is " << largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A + ofs << "\n Largest force is " << largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A << " eV/Angstrom while threshold is " << PARAM.inp.force_thr_ev << " eV/Angstrom" << std::endl; } @@ -156,22 +156,22 @@ void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad) if (Ions_Move_Basic::largest_grad == 0.0) { - GlobalV::ofs_running << " largest force is 0, no movement is possible." << std::endl; - GlobalV::ofs_running << " it may converged, otherwise no movement of atom is allowed." << std::endl; + ofs << " largest force is 0, no movement is possible." << std::endl; + ofs << " it may converged, otherwise no movement of atom is allowed." << std::endl; Ions_Move_Basic::converged = true; } // mohan update 2011-04-21 else if (etot_diff < etot_thr && Ions_Move_Basic::largest_grad < PARAM.inp.force_thr ) { - GlobalV::ofs_running << "\n Ion relaxation is converged!" << std::endl; - GlobalV::ofs_running << "\n Energy difference (Ry) = " << etot_diff << std::endl; + ofs << "\n Ion relaxation is converged!" << std::endl; + ofs << "\n Energy difference (Ry) = " << etot_diff << std::endl; Ions_Move_Basic::converged = true; ++Ions_Move_Basic::update_iter; } else { - GlobalV::ofs_running << "\n Ion relaxation is not converged yet (threshold is " + ofs << "\n Ion relaxation is not converged yet (threshold is " << PARAM.inp.force_thr * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A << ")" << std::endl; // std::cout << "\n etot_diff=" << etot_diff << " etot_thr=" << etot_thr //<< " largest_grad=" << largest_grad << " force_thr=" << PARAM.inp.force_thr << std::endl; @@ -181,16 +181,16 @@ void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad) return; } -void Ions_Move_Basic::terminate(const UnitCell &ucell) +void Ions_Move_Basic::terminate(const UnitCell &ucell, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_Basic", "terminate"); if (Ions_Move_Basic::converged) { - GlobalV::ofs_running << " end of geometry optimization" << std::endl; - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "istep", Ions_Move_Basic::istep); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "update iteration", Ions_Move_Basic::update_iter); + ofs << " end of geometry optimization" << std::endl; + ModuleBase::GlobalFunc::OUT(ofs, "istep", Ions_Move_Basic::istep); + ModuleBase::GlobalFunc::OUT(ofs, "update iteration", Ions_Move_Basic::update_iter); /* - GlobalV::ofs_running<<"Saving the approximate inverse hessian"< +#include #include "relax_data.h" #include "source_base/matrix.h" #include "source_cell/unitcell.h" @@ -42,29 +44,33 @@ extern int out_stru; ///< Structure output flag * @param force Force matrix (nat x 3) * @param pos Output position array (dimension: dim) * @param grad Output gradient array (dimension: dim) + * @param ofs Output stream for logging */ -void setup_gradient(const UnitCell &ucell, const ModuleBase::matrix &force, double *pos, double *grad); +void setup_gradient(const UnitCell &ucell, const ModuleBase::matrix &force, double *pos, double *grad, std::ofstream& ofs); /** * @brief Move atoms according to displacement vector. * @param ucell Unit cell to update * @param move Displacement vector (dimension: dim) * @param pos Current position array (dimension: dim) + * @param ofs Output stream for logging */ -void move_atoms(UnitCell &ucell, double *move, double *pos); +void move_atoms(UnitCell &ucell, double *move, double *pos, std::ofstream& ofs); /** * @brief Check convergence based on gradient threshold. * @param ucell Unit cell containing lattice information * @param grad Gradient array (dimension: dim) + * @param ofs Output stream for logging */ -void check_converged(const UnitCell &ucell, const double *grad); +void check_converged(const UnitCell &ucell, const double *grad, std::ofstream& ofs); /** * @brief Terminate geometry optimization and output results. * @param ucell Unit cell to output + * @param ofs Output stream for logging */ -void terminate(const UnitCell &ucell); +void terminate(const UnitCell &ucell, std::ofstream& ofs); /** * @brief Update energy values and compute energy difference. diff --git a/source/source_relax/ions_move_bfgs.cpp b/source/source_relax/ions_move_bfgs.cpp index 11b712805ba..3330e874aac 100644 --- a/source/source_relax/ions_move_bfgs.cpp +++ b/source/source_relax/ions_move_bfgs.cpp @@ -37,7 +37,7 @@ void Ions_Move_BFGS::allocate() return; } -void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in) +void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_BFGS", "start"); @@ -48,23 +48,23 @@ void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con // In the following steps, the pos is updated by BFGS methods. if (first_step) { - Ions_Move_Basic::setup_gradient(ucell, force, this->pos.data(), this->grad.data()); + Ions_Move_Basic::setup_gradient(ucell, force, this->pos.data(), this->grad.data(), ofs); first_step = false; } else { std::vector pos_tmp(3 * ucell.nat); - Ions_Move_Basic::setup_gradient(ucell, force, pos_tmp.data(), this->grad.data()); + Ions_Move_Basic::setup_gradient(ucell, force, pos_tmp.data(), this->grad.data(), ofs); } // use energy_in and istep to setup etot and etot_old. Ions_Move_Basic::setup_etot(energy_in, false); // use gradient and etot and etot_old to check // if the result is converged. - Ions_Move_Basic::check_converged(ucell, this->grad.data()); + Ions_Move_Basic::check_converged(ucell, this->grad.data(), ofs); if (Ions_Move_Basic::converged) { - Ions_Move_Basic::terminate(ucell); + Ions_Move_Basic::terminate(ucell, ofs); } else { @@ -73,7 +73,7 @@ void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con // [ if run from previous saved info ] // the BFGS file is read from previous run. // and the move_p is renormalized. - this->restart_bfgs(ucell.lat0); + this->restart_bfgs(ucell.lat0, ofs); //[ if etot>etot_p ] // interpolation @@ -81,18 +81,18 @@ void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con // calculate the new step -> the new move using hessian // matrix, and set the new trust radius. // [compute the move at last] - this->bfgs_routine(ucell.lat0); + this->bfgs_routine(ucell.lat0, ofs); // get prepared for the next try. // even if the energy is higher, we save the information. this->save_bfgs(); - Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data()); + Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data(), ofs); } return; } -void Ions_Move_BFGS::restart_bfgs(const double& lat0) +void Ions_Move_BFGS::restart_bfgs(const double& lat0, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_BFGS", "restart_bfgs"); @@ -114,7 +114,7 @@ void Ions_Move_BFGS::restart_bfgs(const double& lat0) if (PARAM.inp.test_relax_method) { - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "trust_radius_old (bohr)", trust_radius_old); + ModuleBase::GlobalFunc::OUT(ofs, "trust_radius_old (bohr)", trust_radius_old); } // (2) @@ -168,7 +168,7 @@ void Ions_Move_BFGS::restart_bfgs(const double& lat0) return; } -void Ions_Move_BFGS::bfgs_routine(const double& lat0) +void Ions_Move_BFGS::bfgs_routine(const double& lat0, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_BFGS", "bfgs_routine"); using namespace Ions_Move_Basic; @@ -229,9 +229,9 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0) if (PARAM.inp.test_relax_method) { - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "dE0s", dE0s); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "den", den); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "interpolated trust radius", trust_radius); + ModuleBase::GlobalFunc::OUT(ofs, "dE0s", dE0s); + ModuleBase::GlobalFunc::OUT(ofs, "den", den); + ModuleBase::GlobalFunc::OUT(ofs, "interpolated trust radius", trust_radius); } // std::cout << " Formula : " << etot << " * s^2 + " << dE0s << " * s + " << etot_p << std::endl; // std::cout << " Lowest point : " << trust_radius << std::endl; @@ -242,7 +242,7 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0) // then do is again, but smaller raidus. trust_radius = 0.5 * trust_radius_old; - GlobalV::ofs_running << " quadratic interpolation is impossible." << std::endl; + ofs << " quadratic interpolation is impossible." << std::endl; } // values from the last succeseful bfgs step are restored etot = etot_p; @@ -257,11 +257,11 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0) // we are trapped in this case..., so the algorithim must be restart // the history is reset // xiaohui add 2013-03-17 - GlobalV::ofs_running << "trust_radius = " << trust_radius << std::endl; - GlobalV::ofs_running << "relax_bfgs_rmin = " << relax_bfgs_rmin << std::endl; - GlobalV::ofs_running << "relax_bfgs_rmax = " << relax_bfgs_rmax << std::endl; + ofs << "trust_radius = " << trust_radius << std::endl; + ofs << "relax_bfgs_rmin = " << relax_bfgs_rmin << std::endl; + ofs << "relax_bfgs_rmax = " << relax_bfgs_rmax << std::endl; // xiaohui add 2013-03-17 - GlobalV::ofs_running << " trust_radius < relax_bfgs_rmin, reset bfgs history." << std::endl; + ofs << " trust_radius < relax_bfgs_rmin, reset bfgs history." << std::endl; if (tr_min_hit) { @@ -293,7 +293,7 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0) } else if (etot <= etot_p) { - this->new_step(lat0); + this->new_step(lat0, ofs); } if (PARAM.inp.out_level == "ie") diff --git a/source/source_relax/ions_move_bfgs.h b/source/source_relax/ions_move_bfgs.h index a9c030b0200..6d75868165a 100644 --- a/source/source_relax/ions_move_bfgs.h +++ b/source/source_relax/ions_move_bfgs.h @@ -1,6 +1,8 @@ #ifndef IONS_MOVE_BFGS_H #define IONS_MOVE_BFGS_H +#include +#include #include "bfgs_basic.h" #include "source_base/matrix.h" #include "source_cell/unitcell.h" @@ -11,12 +13,12 @@ class Ions_Move_BFGS : public BFGS_Basic ~Ions_Move_BFGS(); void allocate(void); - void start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in); + void start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, std::ofstream& ofs); private: bool init_done; - void bfgs_routine(const double& lat0); - void restart_bfgs(const double& lat0); + void bfgs_routine(const double& lat0, std::ofstream& ofs); + void restart_bfgs(const double& lat0, std::ofstream& ofs); bool first_step=true; // If it is the first step of the relaxation. The pos is only generated from ucell in the first step, and in the following steps, the pos is generated from the previous step. }; diff --git a/source/source_relax/ions_move_cg.cpp b/source/source_relax/ions_move_cg.cpp index 00a73f648d6..432d340d86e 100644 --- a/source/source_relax/ions_move_cg.cpp +++ b/source/source_relax/ions_move_cg.cpp @@ -25,7 +25,7 @@ void Ions_Move_CG::allocate(void) this->e0 = 0.0; } -void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in) +void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_CG", "start"); assert(dim > 0); @@ -72,16 +72,16 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const nbrent = 0; } - Ions_Move_Basic::setup_gradient(ucell, force, pos.data(), grad.data()); + Ions_Move_Basic::setup_gradient(ucell, force, pos.data(), grad.data(), ofs); Ions_Move_Basic::setup_etot(etot_in, 0); if (flag == 0) { - Ions_Move_Basic::check_converged(ucell, grad.data()); + Ions_Move_Basic::check_converged(ucell, grad.data(), ofs); } if (Ions_Move_Basic::converged) { - Ions_Move_Basic::terminate(ucell); + Ions_Move_Basic::terminate(ucell, ofs); break; } @@ -93,7 +93,7 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const CG_Base::normalize(dim, cg_gradn.data(), cg_grad.data()); CG_Base::setup_move(dim, move0.data(), cg_gradn.data(), steplength); - Ions_Move_Basic::move_atoms(ucell, move0.data(), pos.data()); + Ions_Move_Basic::move_atoms(ucell, move0.data(), pos.data(), ofs); for (int i = 0; i < dim; i++) { @@ -145,7 +145,7 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const } CG_Base::setup_move(dim, move.data(), cg_gradn.data(), best_x); - Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data()); + Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data(), ofs); trial = false; xa = 0; CG_Base::f_cal(dim, move0.data(), move.data(), xc); @@ -183,7 +183,7 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const CG_Base::normalize(dim, cg_gradn.data(), cg_grad0.data()); CG_Base::setup_move(dim, move.data(), cg_gradn.data(), best_x); - Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data()); + Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data(), ofs); Ions_Move_Basic::relax_bfgs_init = xc; break; } diff --git a/source/source_relax/ions_move_cg.h b/source/source_relax/ions_move_cg.h index d846219e8ec..bd1366c8d01 100644 --- a/source/source_relax/ions_move_cg.h +++ b/source/source_relax/ions_move_cg.h @@ -1,6 +1,8 @@ #ifndef IONS_MOVE_CG_H #define IONS_MOVE_CG_H +#include +#include #include "source_base/matrix.h" #include "source_cell/unitcell.h" #include "cg_base.h" @@ -13,7 +15,7 @@ class Ions_Move_CG : public CG_Base ~Ions_Move_CG() = default; void allocate(void); - void start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot); + void start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, std::ofstream& ofs); static double RELAX_CG_THR; int sd_step = 0; diff --git a/source/source_relax/ions_move_methods.cpp b/source/source_relax/ions_move_methods.cpp index db485f4c09e..d54f2b1b4c0 100644 --- a/source/source_relax/ions_move_methods.cpp +++ b/source/source_relax/ions_move_methods.cpp @@ -53,7 +53,8 @@ void Ions_Move_Methods::cal_movement(const int &istep, const int &force_step, const ModuleBase::matrix &f, const double &etot, - UnitCell &ucell) + UnitCell &ucell, + std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_Methods", "init"); // Ions_Move_Basic::istep = istep; @@ -63,19 +64,19 @@ void Ions_Move_Methods::cal_movement(const int &istep, // move_ions // output tau // check all symmery - bfgs.start(ucell, f, etot); + bfgs.start(ucell, f, etot, ofs); } else if (Ions_Move_Basic::relax_method[0] == "sd") { - sd.start(ucell, f, etot); + sd.start(ucell, f, etot, ofs); } else if (Ions_Move_Basic::relax_method[0] == "cg") { - cg.start(ucell, f, etot); + cg.start(ucell, f, etot, ofs); } else if (Ions_Move_Basic::relax_method[0] == "cg_bfgs") { - cg.start(ucell, f, etot); // added by pengfei 13-8-10 + cg.start(ucell, f, etot, ofs); // added by pengfei 13-8-10 } else if(Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] == "1") { diff --git a/source/source_relax/ions_move_methods.h b/source/source_relax/ions_move_methods.h index b9b4e28611e..a7b4ed84cc9 100644 --- a/source/source_relax/ions_move_methods.h +++ b/source/source_relax/ions_move_methods.h @@ -1,6 +1,8 @@ #ifndef IONS_MOVE_METHODS_H #define IONS_MOVE_METHODS_H +#include +#include #include "ions_move_basic.h" #include "ions_move_bfgs.h" #include "ions_move_cg.h" @@ -20,7 +22,8 @@ class Ions_Move_Methods const int &force_step, const ModuleBase::matrix &f, const double &etot, - UnitCell &ucell); + UnitCell &ucell, + std::ofstream& ofs); bool get_converged() const { diff --git a/source/source_relax/ions_move_sd.cpp b/source/source_relax/ions_move_sd.cpp index 2e0f4f7a322..8405d572d88 100644 --- a/source/source_relax/ions_move_sd.cpp +++ b/source/source_relax/ions_move_sd.cpp @@ -20,7 +20,7 @@ void Ions_Move_SD::allocate() pos_saved.resize(dim, 0.0); } -void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot_in) +void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot_in, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_SD", "start"); @@ -36,7 +36,7 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const // 0: ediff < 0 bool judgement = false; setup_etot(etot_in, judgement); - setup_gradient(ucell, force, pos.data(), grad.data()); + setup_gradient(ucell, force, pos.data(), grad.data(), ofs); if (istep == 1 || etot_in <= energy_saved) { @@ -61,10 +61,10 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const } } - Ions_Move_Basic::check_converged(ucell, grad.data()); + Ions_Move_Basic::check_converged(ucell, grad.data(), ofs); if (Ions_Move_Basic::converged) { - Ions_Move_Basic::terminate(ucell); + Ions_Move_Basic::terminate(ucell, ofs); } else { @@ -73,7 +73,7 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const { move[i] = -grad_saved[i] * trust_radius; } - move_atoms(ucell, move.data(), pos_saved.data()); + move_atoms(ucell, move.data(), pos_saved.data(), ofs); Ions_Move_Basic::update_iter++; } diff --git a/source/source_relax/ions_move_sd.h b/source/source_relax/ions_move_sd.h index e2eb53d587c..69b3c30e6a9 100644 --- a/source/source_relax/ions_move_sd.h +++ b/source/source_relax/ions_move_sd.h @@ -1,6 +1,8 @@ #ifndef IONS_MOVE_SD_H #define IONS_MOVE_SD_H +#include +#include #include "source_base/matrix.h" #include "source_cell/unitcell.h" #include @@ -12,7 +14,7 @@ class Ions_Move_SD ~Ions_Move_SD() = default; void allocate(void); - void start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot); + void start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot, std::ofstream& ofs); private: double energy_saved; diff --git a/source/source_relax/relax_nsync.cpp b/source/source_relax/relax_nsync.cpp index 9541c9dc177..81f64e47bf7 100644 --- a/source/source_relax/relax_nsync.cpp +++ b/source/source_relax/relax_nsync.cpp @@ -49,7 +49,7 @@ bool Relax_old::relax_step(const int& istep, { // do relax calculation and generate next structure bool converged = false; - converged = this->do_relax(istep, force, energy, ucell, force_step); + converged = this->do_relax(istep, force, energy, ucell, force_step, GlobalV::ofs_running); if (!converged) { ucell.ionic_position_updated = true; @@ -129,10 +129,11 @@ bool Relax_old::do_relax(const int& istep, const ModuleBase::matrix& ionic_force, const double& total_energy, UnitCell& ucell, - int& jstep) + int& jstep, + std::ofstream& ofs) { ModuleBase::TITLE("Relax_old", "do_relax"); - IMM.cal_movement(istep, jstep, ionic_force, total_energy, ucell); + IMM.cal_movement(istep, jstep, ionic_force, total_energy, ucell, ofs); ++jstep; return IMM.get_converged(); } diff --git a/source/source_relax/relax_nsync.h b/source/source_relax/relax_nsync.h index 33eca958020..d98525d536b 100644 --- a/source/source_relax/relax_nsync.h +++ b/source/source_relax/relax_nsync.h @@ -1,6 +1,7 @@ #ifndef RELAX_OLD_H #define RELAX_OLD_H +#include #include "ions_move_methods.h" #include "lattice_change_methods.h" #include "source_cell/unitcell.h" @@ -28,7 +29,8 @@ class Relax_old const ModuleBase::matrix& ionic_force, const double& total_energy, UnitCell& ucell, - int& jstep); + int& jstep, + std::ofstream& ofs); bool do_cellrelax(const int& istep, const int& stress_step, const ModuleBase::matrix& stress, diff --git a/source/source_relax/test/bfgs_basic_test.cpp b/source/source_relax/test/bfgs_basic_test.cpp index efd30e9829e..184632a8976 100644 --- a/source/source_relax/test/bfgs_basic_test.cpp +++ b/source/source_relax/test/bfgs_basic_test.cpp @@ -57,7 +57,10 @@ TEST_F(BFGSBasicTest, UpdateInverseHessianDeath) { Ions_Move_Basic::dim = 0; double lat0 = 1.0; - ASSERT_DEATH(bfgs.update_inverse_hessian(lat0), ""); + std::ofstream ofs("test_log_update_inverse_hessian_death.log"); + ASSERT_DEATH(bfgs.update_inverse_hessian(lat0, ofs), ""); + ofs.close(); + std::remove("test_log_update_inverse_hessian_death.log"); } // Test function update_inverse_hessian() when sdoty = 0 @@ -67,18 +70,18 @@ TEST_F(BFGSBasicTest, UpdateInverseHessianCase1) double lat0 = 1.0; bfgs.allocate_basic(); - GlobalV::ofs_running.open("log"); - bfgs.update_inverse_hessian(lat0); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_log_update_inverse_hessian_case1.log"); + bfgs.update_inverse_hessian(lat0, ofs); + ofs.close(); std::string expected_output = " WARINIG: unexpected behaviour in update_inverse_hessian\n Resetting bfgs history \n"; - std::ifstream ifs("log"); + std::ifstream ifs("test_log_update_inverse_hessian_case1.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); + std::remove("test_log_update_inverse_hessian_case1.log"); EXPECT_EQ(expected_output, output); - std::remove("log"); } // Test function update_inverse_hessian() @@ -90,7 +93,9 @@ TEST_F(BFGSBasicTest, UpdateInverseHessianCase2) bfgs.pos[0] = 2.0; bfgs.grad[0] = 2.0; - bfgs.update_inverse_hessian(lat0); + std::ofstream ofs("test_log_update_inverse_hessian_case2.log"); + bfgs.update_inverse_hessian(lat0, ofs); + ofs.close(); EXPECT_DOUBLE_EQ(bfgs.inv_hess(0, 0), 0.5); EXPECT_DOUBLE_EQ(bfgs.inv_hess(0, 1), 0.0); @@ -101,6 +106,7 @@ TEST_F(BFGSBasicTest, UpdateInverseHessianCase2) EXPECT_DOUBLE_EQ(bfgs.inv_hess(2, 0), 0.0); EXPECT_DOUBLE_EQ(bfgs.inv_hess(2, 1), 0.0); EXPECT_DOUBLE_EQ(bfgs.inv_hess(2, 2), 0.0); + std::remove("test_log_update_inverse_hessian_case2.log"); } // Test function check_wolfe_conditions() @@ -114,9 +120,9 @@ TEST_F(BFGSBasicTest, CheckWolfeConditions) bfgs.grad[0] = 2.0; bfgs.move[0] = 1.0; - GlobalV::ofs_running.open("log"); - bfgs.check_wolfe_conditions(); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_log_check_wolfe_conditions.log"); + bfgs.check_wolfe_conditions(ofs); + ofs.close(); std::string expected_output = " etot - etot_p = 10\n relax_bfgs_w1 * dot_p = -0\n " @@ -125,13 +131,14 @@ TEST_F(BFGSBasicTest, CheckWolfeConditions) "wolfe1 = 0\n wolfe2 = 0\n etot - etot_p = 10\n " " relax_bfgs_w1 * dot_p = -0\n wolfe1 = 0\n " " wolfe2 = 0\n wolfe condition satisfied = 0\n"; - std::ifstream ifs("log"); + + std::ifstream ifs("test_log_check_wolfe_conditions.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); + std::remove("test_log_check_wolfe_conditions.log"); EXPECT_EQ(bfgs.wolfe_flag, false); EXPECT_EQ(expected_output, output); - std::remove("log"); } // Test function reset_hessian() @@ -195,7 +202,8 @@ TEST_F(BFGSBasicTest, NewStepCase1) bfgs.inv_hess(1, 1) = -6.0; double lat0 = 1.0; - bfgs.new_step(lat0); + std::ofstream ofs("test_log.log"); + bfgs.new_step(lat0, ofs); EXPECT_EQ(Ions_Move_Basic::update_iter, 1); EXPECT_EQ(bfgs.tr_min_hit, false); @@ -228,7 +236,8 @@ TEST_F(BFGSBasicTest, NewStepCase2) bfgs.inv_hess(1, 1) = -6.0; double lat0 = 1.0; - bfgs.new_step(lat0); + std::ofstream ofs("test_log.log"); + bfgs.new_step(lat0, ofs); EXPECT_EQ(Ions_Move_Basic::update_iter, 3); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, -1.0); @@ -247,9 +256,10 @@ TEST_F(BFGSBasicTest, NewStepWarningQuit) bfgs.bfgs_ndim = 2; bfgs.allocate_basic(); double lat0 = 1.0; + std::ofstream ofs("test_log.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.new_step(lat0), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.new_step(lat0, ofs), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("bfgs_ndim > 1 not implemented yet")); } @@ -270,7 +280,8 @@ TEST_F(BFGSBasicTest, ComputeTrustRadiusCase1) bfgs.wolfe_flag = true; bfgs.relax_bfgs_w1 = 1.0; - bfgs.compute_trust_radius(); + std::ofstream ofs("test_log.log"); + bfgs.compute_trust_radius(ofs); EXPECT_EQ(bfgs.tr_min_hit, false); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, -1.0); @@ -303,7 +314,8 @@ TEST_F(BFGSBasicTest, ComputeTrustRadiusCase2) bfgs.relax_bfgs_w1 = 1.0; bfgs.tr_min_hit = false; - bfgs.compute_trust_radius(); + std::ofstream ofs("test_log.log"); + bfgs.compute_trust_radius(ofs); EXPECT_EQ(bfgs.tr_min_hit, true); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, 100.0); @@ -336,8 +348,9 @@ TEST_F(BFGSBasicTest, ComputeTrustRadiusWarningQuit) bfgs.relax_bfgs_w1 = 1.0; bfgs.tr_min_hit = true; + std::ofstream ofs("test_log.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.compute_trust_radius(), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.compute_trust_radius(ofs), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("bfgs history already reset at previous step, we got trapped!")); } \ No newline at end of file diff --git a/source/source_relax/test/ions_move_basic_test.cpp b/source/source_relax/test/ions_move_basic_test.cpp index b6f02628aec..dd980d57f5a 100644 --- a/source/source_relax/test/ions_move_basic_test.cpp +++ b/source/source_relax/test/ions_move_basic_test.cpp @@ -42,7 +42,10 @@ TEST_F(IonsMoveBasicTest, SetupGradient) { // Call the function being tested Ions_Move_Basic::dim = 6; - Ions_Move_Basic::setup_gradient(ucell, force, pos, grad); + std::ofstream ofs("test_setup_gradient.log"); + Ions_Move_Basic::setup_gradient(ucell, force, pos, grad, ofs); + ofs.close(); + std::remove("test_setup_gradient.log"); // Check that the expected positions and gradients were generated EXPECT_DOUBLE_EQ(pos[0], 0.0); @@ -72,18 +75,18 @@ TEST_F(IonsMoveBasicTest, MoveAtoms) } // Call the function being tested - GlobalV::ofs_running.open("log"); - Ions_Move_Basic::move_atoms(ucell, move, pos); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_move_atoms.log"); + Ions_Move_Basic::move_atoms(ucell, move, pos, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_move_atoms.log"); std::string expected_output = "\n movement of ions (unit is Bohr) : \n Atom x y " " z\n move_1 0 1 2\n " "move_2 3 4 5\n"; std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_move_atoms.log"); EXPECT_THAT(output , ::testing::HasSubstr(expected_output)); EXPECT_DOUBLE_EQ(pos[0], 0.0); @@ -108,17 +111,17 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase1) } // Call the function being tested - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_check_converged_case1.log"); testing::internal::CaptureStdout(); - Ions_Move_Basic::check_converged(ucell, grad); + Ions_Move_Basic::check_converged(ucell, grad, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); - GlobalV::ofs_running.close(); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_check_converged_case1.log"); std::string ofs_output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_check_converged_case1.log"); std::string expected_ofs = " old total energy (ry) = 0\n new total energy (ry) = 0\n " @@ -147,17 +150,17 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase2) grad[0] = 1.0; // Call the function being tested - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_check_converged_case2.log"); testing::internal::CaptureStdout(); - Ions_Move_Basic::check_converged(ucell, grad); + Ions_Move_Basic::check_converged(ucell, grad, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); - GlobalV::ofs_running.close(); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_check_converged_case2.log"); std::string ofs_output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_check_converged_case2.log"); std::string expected_ofs = " old total energy (ry) = 0\n new total energy (ry) = 0\n " @@ -186,17 +189,17 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase3) grad[0] = 1.0; // Call the function being tested - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_check_converged_case3.log"); testing::internal::CaptureStdout(); - Ions_Move_Basic::check_converged(ucell, grad); + Ions_Move_Basic::check_converged(ucell, grad, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); - GlobalV::ofs_running.close(); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_check_converged_case3.log"); std::string ofs_output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_check_converged_case3.log"); std::string expected_ofs = " old total energy (ry) = 0\n new total energy (ry) = 0\n " @@ -221,15 +224,15 @@ TEST_F(IonsMoveBasicTest, TerminateConverged) Ions_Move_Basic::update_iter = 5; // Call the function being tested - GlobalV::ofs_running.open("log"); - Ions_Move_Basic::terminate(ucell); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_terminate_converged.log"); + Ions_Move_Basic::terminate(ucell, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_terminate_converged.log"); std::string ofs_output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_terminate_converged.log"); std::string expected_ofs = " end of geometry optimization\n istep = 2\n " " update iteration = 5\n"; @@ -244,15 +247,15 @@ TEST_F(IonsMoveBasicTest, TerminateNotConverged) Ions_Move_Basic::converged = false; // Call the function being tested - GlobalV::ofs_running.open("log"); - Ions_Move_Basic::terminate(ucell); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_terminate_not_converged.log"); + Ions_Move_Basic::terminate(ucell, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_terminate_not_converged.log"); std::string ofs_output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_terminate_not_converged.log"); std::string expected_ofs = " the maximum number of steps has been reached.\n end of geometry optimization.\n"; diff --git a/source/source_relax/test/ions_move_bfgs_test.cpp b/source/source_relax/test/ions_move_bfgs_test.cpp index f13ef8c3ea5..8ad773bbf55 100644 --- a/source/source_relax/test/ions_move_bfgs_test.cpp +++ b/source/source_relax/test/ions_move_bfgs_test.cpp @@ -73,15 +73,15 @@ TEST_F(IonsMoveBFGSTest, StartCase1) // Call the function being tested bfgs.allocate(); - GlobalV::ofs_running.open("log"); - bfgs.start(ucell, force, energy_in); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_start_case1.log"); + bfgs.start(ucell, force, energy_in, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_start_case1.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_start_case1.log"); EXPECT_THAT(output, testing::HasSubstr("update iteration")); } @@ -99,15 +99,18 @@ TEST_F(IonsMoveBFGSTest, StartCase2) // Call the function being tested bfgs.allocate(); - GlobalV::ofs_running.open("log"); - EXPECT_EXIT(bfgs.start(ucell, force, energy_in) , ::testing::ExitedWithCode(1), ""); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_start_case2.log"); + testing::internal::CaptureStderr(); + EXPECT_EXIT(bfgs.start(ucell, force, energy_in, ofs) , ::testing::ExitedWithCode(1), ""); + std::string stderr_output = testing::internal::GetCapturedStderr(); + ofs.close(); + std::remove("test_start_case2.log"); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_start_case2.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_start_case2.log"); EXPECT_THAT(output, testing::HasSubstr("Ion relaxation is not converged yet")); } @@ -129,15 +132,15 @@ TEST_F(IonsMoveBFGSTest, RestartBfgsCase1) } // Call the function being tested - GlobalV::ofs_running.open("log"); - bfgs.restart_bfgs(lat0); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_restart_bfgs_case1.log"); + bfgs.restart_bfgs(lat0, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_restart_bfgs_case1.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_restart_bfgs_case1.log"); std::string expected_output = " trust_radius_old (bohr) = 2.44949\n"; @@ -167,7 +170,10 @@ TEST_F(IonsMoveBFGSTest, RestartBfgsCase2) } // Call the function being tested - bfgs.restart_bfgs(lat0); + std::ofstream ofs("test_restart_bfgs_case2.log"); + bfgs.restart_bfgs(lat0, ofs); + ofs.close(); + std::remove("test_restart_bfgs_case2.log"); // Check the results EXPECT_DOUBLE_EQ(Ions_Move_Basic::update_iter, 0.0); @@ -212,17 +218,17 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase1) } // Call the function being tested - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_bfgs_routine_case1.log"); testing::internal::CaptureStdout(); - bfgs.bfgs_routine(lat0); + bfgs.bfgs_routine(lat0, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); - GlobalV::ofs_running.close(); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_bfgs_routine_case1.log"); std::string ofs_output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_bfgs_routine_case1.log"); std::string expected_ofs = " dE0s = 0\n den = 0.1\n " @@ -278,17 +284,17 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase2) } // Call the function being tested - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_bfgs_routine_case2.log"); testing::internal::CaptureStdout(); - bfgs.bfgs_routine(lat0); + bfgs.bfgs_routine(lat0, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); - GlobalV::ofs_running.close(); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_bfgs_routine_case2.log"); std::string ofs_output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_bfgs_routine_case2.log"); std::string expected_ofs = " quadratic interpolation is impossible.\n istep = " "0\n update iteration = 0\n"; @@ -339,15 +345,15 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase3) bfgs.inv_hess(1, 1) = -6.0; // Call the function being tested - GlobalV::ofs_running.open("log"); - bfgs.bfgs_routine(lat0); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_bfgs_routine_case3.log"); + bfgs.bfgs_routine(lat0, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_bfgs_routine_case3.log"); std::string ofs_output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_bfgs_routine_case3.log"); std::string expected_ofs = " check the norm of new move 410 (Bohr)\n Uphill move : resetting bfgs history\n " " istep = 0\n update iteration = 1\n"; @@ -397,9 +403,12 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit1) } // Check the results + std::ofstream ofs("test_bfgs_routine_warning_quit1.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.bfgs_routine(lat0), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.bfgs_routine(lat0, ofs), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); + ofs.close(); + std::remove("test_bfgs_routine_warning_quit1.log"); EXPECT_THAT(output, testing::HasSubstr("trust radius is too small! Break down.")); } @@ -418,8 +427,11 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit2) Ions_Move_Basic::relax_bfgs_rmin = 1.0; // Check the results + std::ofstream ofs("test_bfgs_routine_warning_quit2.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.bfgs_routine(lat0), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.bfgs_routine(lat0, ofs), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); + ofs.close(); + std::remove("test_bfgs_routine_warning_quit2.log"); EXPECT_THAT(output, testing::HasSubstr("BFGS: move-length unreasonably short")); } diff --git a/source/source_relax/test/ions_move_cg_test.cpp b/source/source_relax/test/ions_move_cg_test.cpp index 83c4323be11..a811e66c9c4 100644 --- a/source/source_relax/test/ions_move_cg_test.cpp +++ b/source/source_relax/test/ions_move_cg_test.cpp @@ -99,9 +99,9 @@ TEST_F(IonsMoveCGTest, TestStartConverged) double etot = 0.0; // call function - GlobalV::ofs_running.open("TestStartConverged.log"); - im_cg.start(ucell, force, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("TestStartConverged.log"); + im_cg.start(ucell, force, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Largest force is 0 eV/Angstrom while threshold is -1 eV/Angstrom\n" @@ -137,9 +137,9 @@ TEST_F(IonsMoveCGTest, TestStartSd) double etot = 0.0; // call function - GlobalV::ofs_running.open("TestStartSd.log"); - im_cg.start(ucell, force, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("TestStartSd.log"); + im_cg.start(ucell, force, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Largest force is 0.257111 eV/Angstrom while threshold is -1 eV/Angstrom\n\n" @@ -172,13 +172,16 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) // call function im_cg.move0[0] = 1.0; - im_cg.start(ucell, force, etot); + std::ofstream ofs1("TestStartTrialGoto_temp1.log"); + im_cg.start(ucell, force, etot, ofs1); + ofs1.close(); + std::remove("TestStartTrialGoto_temp1.log"); Ions_Move_Basic::istep = 2; im_cg.move0[0] = 10.0; force(0, 0) = 0.001; - GlobalV::ofs_running.open("TestStartTrialGoto.log"); - im_cg.start(ucell, force, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("TestStartTrialGoto.log"); + im_cg.start(ucell, force, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Largest force is 0.0257111 eV/Angstrom while threshold is -1 eV/Angstrom\n\n" @@ -211,12 +214,15 @@ TEST_F(IonsMoveCGTest, TestStartTrial) // call function im_cg.move0[0] = 1.0; - im_cg.start(ucell, force, etot); + std::ofstream ofs1("TestStartTrial_temp1.log"); + im_cg.start(ucell, force, etot, ofs1); + ofs1.close(); + std::remove("TestStartTrial_temp1.log"); Ions_Move_Basic::istep = 2; im_cg.move0[0] = 10.0; - GlobalV::ofs_running.open("TestStartTrial.log"); - im_cg.start(ucell, force, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("TestStartTrial.log"); + im_cg.start(ucell, force, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Largest force is 0.257111 eV/Angstrom while threshold is -1 eV/Angstrom\n\n" @@ -249,14 +255,20 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) // call function im_cg.move0[0] = 1.0; - im_cg.start(ucell, force, etot); + std::ofstream ofs1("TestStartNoTrialGotoCase1_temp1.log"); + im_cg.start(ucell, force, etot, ofs1); + ofs1.close(); + std::remove("TestStartNoTrialGotoCase1_temp1.log"); Ions_Move_Basic::istep = 2; - im_cg.start(ucell, force, etot); + std::ofstream ofs2("TestStartNoTrialGotoCase1_temp2.log"); + im_cg.start(ucell, force, etot, ofs2); + ofs2.close(); + std::remove("TestStartNoTrialGotoCase1_temp2.log"); im_cg.move0[0] = 1.0; force(0, 0) = 0.001; - GlobalV::ofs_running.open("TestStartNoTrialGotoCase1.log"); - im_cg.start(ucell, force, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("TestStartNoTrialGotoCase1.log"); + im_cg.start(ucell, force, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Largest force is 0.0257111 eV/Angstrom while threshold is -1 eV/Angstrom\n\n" @@ -289,13 +301,19 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) // call function im_cg.move0[0] = 1.0; - im_cg.start(ucell, force, etot); + std::ofstream ofs1("TestStartNoTrialGotoCase2_temp1.log"); + im_cg.start(ucell, force, etot, ofs1); + ofs1.close(); + std::remove("TestStartNoTrialGotoCase2_temp1.log"); Ions_Move_Basic::istep = 2; im_cg.move0[0] = 10.0; - im_cg.start(ucell, force, etot); - GlobalV::ofs_running.open("TestStartNoTrialGotoCase2.log"); - im_cg.start(ucell, force, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs2("TestStartNoTrialGotoCase2_temp2.log"); + im_cg.start(ucell, force, etot, ofs2); + ofs2.close(); + std::remove("TestStartNoTrialGotoCase2_temp2.log"); + std::ofstream ofs("TestStartNoTrialGotoCase2.log"); + im_cg.start(ucell, force, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Largest force is 0.257111 eV/Angstrom while threshold is -1 eV/Angstrom\n\n" @@ -328,14 +346,20 @@ TEST_F(IonsMoveCGTest, TestStartNoTrial) // call function im_cg.move0[0] = 1.0; - im_cg.start(ucell, force, etot); + std::ofstream ofs1("TestStartNoTrial_temp1.log"); + im_cg.start(ucell, force, etot, ofs1); + ofs1.close(); + std::remove("TestStartNoTrial_temp1.log"); Ions_Move_Basic::istep = 2; im_cg.move0[0] = 1.0; force(0, 0) = 0.001; - im_cg.start(ucell, force, etot); - GlobalV::ofs_running.open("TestStartNoTrial.log"); - im_cg.start(ucell, force, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs2("TestStartNoTrial_temp2.log"); + im_cg.start(ucell, force, etot, ofs2); + ofs2.close(); + std::remove("TestStartNoTrial_temp2.log"); + std::ofstream ofs("TestStartNoTrial.log"); + im_cg.start(ucell, force, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Largest force is 0.0257111 eV/Angstrom while threshold is -1 eV/Angstrom\n\n" diff --git a/source/source_relax/test/ions_move_sd_test.cpp b/source/source_relax/test/ions_move_sd_test.cpp index 647247ecd38..328cb831c40 100644 --- a/source/source_relax/test/ions_move_sd_test.cpp +++ b/source/source_relax/test/ions_move_sd_test.cpp @@ -74,19 +74,19 @@ TEST_F(IonsMoveSDTest, TestStartConverged) double etot = 0.0; // call function - GlobalV::ofs_running.open("log"); - im_sd.start(ucell, force, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_sd_start_converged.log"); + im_sd.start(ucell, force, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Largest force is 0 eV/Angstrom while threshold is -1 eV/Angstrom\n" " largest force is 0, no movement is possible.\n it may converged, otherwise no " "movement of atom is allowed.\n end of geometry optimization\n " " istep = 1\n update iteration = 5\n"; - std::ifstream ifs("log"); + std::ifstream ifs("test_sd_start_converged.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_sd_start_converged.log"); std::regex pattern(R"(==> .*::.*\t[\d\.]+ GB\t\d+ s\n )"); output = std::regex_replace(output, pattern, ""); @@ -127,17 +127,17 @@ TEST_F(IonsMoveSDTest, TestStartNotConverged) } // call function - GlobalV::ofs_running.open("log"); - im_sd.start(ucell, force, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_sd_start_not_converged.log"); + im_sd.start(ucell, force, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Largest force is 25.7111 eV/Angstrom while threshold is -1 eV/Angstrom\n\n" " Ion relaxation is not converged yet (threshold is 0.0257111)\n"; - std::ifstream ifs("log"); + std::ifstream ifs("test_sd_start_not_converged.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); ifs.close(); - std::remove("log"); + std::remove("test_sd_start_not_converged.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); EXPECT_EQ(Ions_Move_Basic::converged, false); From 218a80ae71454f3e8c0ede9cbe2d5c52646452c5 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Wed, 10 Jun 2026 08:24:42 +0800 Subject: [PATCH 17/50] fix bug --- source/source_relax/test/lattice_change_methods_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/source_relax/test/lattice_change_methods_test.cpp b/source/source_relax/test/lattice_change_methods_test.cpp index dfc7fbddb5f..69b95ac8922 100644 --- a/source/source_relax/test/lattice_change_methods_test.cpp +++ b/source/source_relax/test/lattice_change_methods_test.cpp @@ -78,7 +78,7 @@ TEST_F(LatticeChangeMethodsTest, GetConverged) lcm.get_converged(); // Assert that the static variable converged is set to false - EXPECT_EQ(Lattice_Change_Basic::converged, true); + EXPECT_EQ(Lattice_Change_Basic::converged, false); } // Test the get_ediff function @@ -97,4 +97,4 @@ TEST_F(LatticeChangeMethodsTest, GetLargestGrad) // Assert that the static variable largest_grad is set to 0.0 EXPECT_DOUBLE_EQ(Lattice_Change_Basic::largest_grad, 0.0); -} \ No newline at end of file +} From f4d2b57fa4afc7bf06c5241c78e151154e656cbf Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Wed, 10 Jun 2026 08:35:51 +0800 Subject: [PATCH 18/50] remove GlobalV::ofs_running --- source/source_relax/lattice_change_basic.cpp | 30 ++--- source/source_relax/lattice_change_basic.h | 7 +- source/source_relax/lattice_change_cg.cpp | 6 +- source/source_relax/lattice_change_cg.h | 3 +- .../source_relax/lattice_change_methods.cpp | 5 +- source/source_relax/lattice_change_methods.h | 4 +- source/source_relax/relax_nsync.cpp | 7 +- source/source_relax/relax_nsync.h | 3 +- .../test/lattice_change_basic_test.cpp | 81 ++++++------- .../test/lattice_change_cg_test.cpp | 110 +++++++++++------- .../test/lattice_change_methods_test.cpp | 6 +- 11 files changed, 149 insertions(+), 113 deletions(-) diff --git a/source/source_relax/lattice_change_basic.cpp b/source/source_relax/lattice_change_basic.cpp index 6c2ca4b68f2..f8cbafa024e 100644 --- a/source/source_relax/lattice_change_basic.cpp +++ b/source/source_relax/lattice_change_basic.cpp @@ -231,7 +231,7 @@ void Lattice_Change_Basic::change_lattice(UnitCell &ucell, double *move, double return; } -void Lattice_Change_Basic::check_converged(const UnitCell &ucell, ModuleBase::matrix &stress, double *grad) +void Lattice_Change_Basic::check_converged(const UnitCell &ucell, ModuleBase::matrix &stress, double *grad, std::ofstream& ofs) { ModuleBase::TITLE("Lattice_Change_Basic", "check_converged"); @@ -273,22 +273,22 @@ void Lattice_Change_Basic::check_converged(const UnitCell &ucell, ModuleBase::ma if (Lattice_Change_Basic::largest_grad == 0.0) { - GlobalV::ofs_running << " Largest stress is 0, movement is impossible." << std::endl; + ofs << " Largest stress is 0, movement is impossible." << std::endl; Lattice_Change_Basic::converged = true; } else if (ucell.lc[0] == 1 && ucell.lc[1] == 1 && ucell.lc[2] == 1) { if (Lattice_Change_Basic::largest_grad < PARAM.inp.stress_thr && stress_ii_max < PARAM.inp.stress_thr) { - GlobalV::ofs_running << "\n Geometry relaxation is converged!" << std::endl; - GlobalV::ofs_running << "\n Largest stress is " << largest_grad + ofs << "\n Geometry relaxation is converged!" << std::endl; + ofs << "\n Largest stress is " << largest_grad << " kbar while threshold is " << PARAM.inp.stress_thr << " kbar" << std::endl; Lattice_Change_Basic::converged = true; ++Lattice_Change_Basic::update_iter; } else { - GlobalV::ofs_running << "\n Geometry relaxation is not converged because threshold is " << PARAM.inp.stress_thr + ofs << "\n Geometry relaxation is not converged because threshold is " << PARAM.inp.stress_thr << " kbar" << std::endl; Lattice_Change_Basic::converged = false; } @@ -298,15 +298,15 @@ void Lattice_Change_Basic::check_converged(const UnitCell &ucell, ModuleBase::ma // the code is almost the same as previous codes if (Lattice_Change_Basic::largest_grad < 10 * PARAM.inp.stress_thr) { - GlobalV::ofs_running << "\n Geometry relaxation is converged!" << std::endl; - GlobalV::ofs_running << "\n Largest stress is " << largest_grad + ofs << "\n Geometry relaxation is converged!" << std::endl; + ofs << "\n Largest stress is " << largest_grad << " kbar while threshold is " << PARAM.inp.stress_thr << " kbar" << std::endl; Lattice_Change_Basic::converged = true; ++Lattice_Change_Basic::update_iter; } else { - GlobalV::ofs_running << "\n Geometry relaxation is not converged because threshold is " << PARAM.inp.stress_thr + ofs << "\n Geometry relaxation is not converged because threshold is " << PARAM.inp.stress_thr << " kbar" << std::endl; Lattice_Change_Basic::converged = false; } @@ -315,16 +315,16 @@ void Lattice_Change_Basic::check_converged(const UnitCell &ucell, ModuleBase::ma return; } -void Lattice_Change_Basic::terminate() +void Lattice_Change_Basic::terminate(std::ofstream& ofs) { ModuleBase::TITLE("Lattice_Change_Basic", "terminate"); if (Lattice_Change_Basic::converged) { - GlobalV::ofs_running << " end of lattice optimization" << std::endl; - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "stress_step", Lattice_Change_Basic::stress_step); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "update iteration", Lattice_Change_Basic::update_iter); + ofs << " end of lattice optimization" << std::endl; + ModuleBase::GlobalFunc::OUT(ofs, "stress_step", Lattice_Change_Basic::stress_step); + ModuleBase::GlobalFunc::OUT(ofs, "update iteration", Lattice_Change_Basic::update_iter); /* - GlobalV::ofs_running<<"Saving the approximate inverse hessian"< #include "relax_data.h" #include "source_base/matrix.h" #include "source_cell/unitcell.h" @@ -52,13 +53,15 @@ void change_lattice(UnitCell &ucell, double *move, double *lat); * @param ucell Unit cell containing lattice constraints * @param stress Stress tensor (3x3 matrix) * @param grad Gradient array (9 elements) + * @param ofs Output stream for logging */ -void check_converged(const UnitCell &ucell, ModuleBase::matrix &stress, double *grad); +void check_converged(const UnitCell &ucell, ModuleBase::matrix &stress, double *grad, std::ofstream& ofs); /** * @brief Terminate lattice optimization and output results. + * @param ofs Output stream for logging */ -void terminate(void); +void terminate(std::ofstream& ofs); /** * @brief Update energy values and compute energy difference. diff --git a/source/source_relax/lattice_change_cg.cpp b/source/source_relax/lattice_change_cg.cpp index 601da813181..c1f51153481 100644 --- a/source/source_relax/lattice_change_cg.cpp +++ b/source/source_relax/lattice_change_cg.cpp @@ -24,7 +24,7 @@ void Lattice_Change_CG::allocate(void) this->e0 = 0.0; } -void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in) +void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs) { ModuleBase::TITLE("Lattice_Change_CG", "start"); @@ -81,12 +81,12 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ if (flag == 0) { - Lattice_Change_Basic::check_converged(ucell, stress, grad.data()); + Lattice_Change_Basic::check_converged(ucell, stress, grad.data(), ofs); } if (Lattice_Change_Basic::converged) { - Lattice_Change_Basic::terminate(); + Lattice_Change_Basic::terminate(ofs); break; } diff --git a/source/source_relax/lattice_change_cg.h b/source/source_relax/lattice_change_cg.h index a2302cb26d9..6e10333c35e 100644 --- a/source/source_relax/lattice_change_cg.h +++ b/source/source_relax/lattice_change_cg.h @@ -1,6 +1,7 @@ #ifndef LATTICE_CHANGE_CG_H #define LATTICE_CHANGE_CG_H +#include #include "source_base/matrix.h" #include "source_cell/unitcell.h" #include "cg_base.h" @@ -14,7 +15,7 @@ class Lattice_Change_CG : public CG_Base ~Lattice_Change_CG() = default; void allocate(void); - void start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot); + void start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot, std::ofstream& ofs); private: std::vector lat0; diff --git a/source/source_relax/lattice_change_methods.cpp b/source/source_relax/lattice_change_methods.cpp index dadd0b3f231..72b3adcdd72 100644 --- a/source/source_relax/lattice_change_methods.cpp +++ b/source/source_relax/lattice_change_methods.cpp @@ -21,13 +21,14 @@ void Lattice_Change_Methods::cal_lattice_change(const int &istep, const int &stress_step, const ModuleBase::matrix &stress, const double &etot, - UnitCell &ucell) + UnitCell &ucell, + std::ofstream& ofs) { ModuleBase::TITLE("Lattice_Change_Methods", "lattice_change_init"); Lattice_Change_Basic::istep = istep; Lattice_Change_Basic::stress_step = stress_step; - lccg.start(ucell, stress, etot); + lccg.start(ucell, stress, etot, ofs); return; } diff --git a/source/source_relax/lattice_change_methods.h b/source/source_relax/lattice_change_methods.h index c8f4344f6dd..bccafaeb7f1 100644 --- a/source/source_relax/lattice_change_methods.h +++ b/source/source_relax/lattice_change_methods.h @@ -1,6 +1,7 @@ #ifndef LATTICE_CHANGE_METHODS_H #define LATTICE_CHANGE_METHODS_H +#include #include "lattice_change_basic.h" #include "lattice_change_cg.h" @@ -17,7 +18,8 @@ class Lattice_Change_Methods const int &stress_step, const ModuleBase::matrix &stress, const double &etot, - UnitCell &ucell); + UnitCell &ucell, + std::ofstream& ofs); bool get_converged(void) const { diff --git a/source/source_relax/relax_nsync.cpp b/source/source_relax/relax_nsync.cpp index 81f64e47bf7..75c5c320c57 100644 --- a/source/source_relax/relax_nsync.cpp +++ b/source/source_relax/relax_nsync.cpp @@ -64,7 +64,7 @@ bool Relax_old::relax_step(const int& istep, { // do cell relax calculation and generate next structure bool converged = false; - converged = this->do_cellrelax(istep, stress_step, stress, energy, ucell); + converged = this->do_cellrelax(istep, stress_step, stress, energy, ucell, GlobalV::ofs_running); if (!converged) { force_step = 1; @@ -141,9 +141,10 @@ bool Relax_old::do_cellrelax(const int& istep, const int& stress_step, const ModuleBase::matrix& stress, const double& total_energy, - UnitCell& ucell) + UnitCell& ucell, + std::ofstream& ofs) { ModuleBase::TITLE("Relax_old", "do_cellrelax"); - LCM.cal_lattice_change(istep, stress_step, stress, total_energy, ucell); + LCM.cal_lattice_change(istep, stress_step, stress, total_energy, ucell, ofs); return LCM.get_converged(); } diff --git a/source/source_relax/relax_nsync.h b/source/source_relax/relax_nsync.h index d98525d536b..c87fd15cada 100644 --- a/source/source_relax/relax_nsync.h +++ b/source/source_relax/relax_nsync.h @@ -35,7 +35,8 @@ class Relax_old const int& stress_step, const ModuleBase::matrix& stress, const double& total_energy, - UnitCell& ucell); + UnitCell& ucell, + std::ofstream& ofs); }; #endif \ No newline at end of file diff --git a/source/source_relax/test/lattice_change_basic_test.cpp b/source/source_relax/test/lattice_change_basic_test.cpp index 2742d39f5b9..61b4c56ddd2 100644 --- a/source/source_relax/test/lattice_change_basic_test.cpp +++ b/source/source_relax/test/lattice_change_basic_test.cpp @@ -1,3 +1,4 @@ +#include #include "source_relax/lattice_change_basic.h" #include "source_relax/relax_data.h" #include "mock_remake_cell.h" @@ -222,7 +223,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase1) // Set up test data Lattice_Change_Basic::update_iter = 0; PARAM.input.stress_thr = 10.0; - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_check_converged_case1.log"); ucell.lc[0] = 1; ucell.lc[1] = 1; ucell.lc[2] = 1; @@ -237,11 +238,11 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase1) stress(2, 2) = 9.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad); - GlobalV::ofs_running.close(); + Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_check_converged_case1.log"); std::string expected_output = "\n Geometry relaxation is not converged because threshold is 10 kbar\n"; std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(output, expected_output); @@ -250,7 +251,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase1) EXPECT_FALSE(Lattice_Change_Basic::converged); ifs.close(); - std::remove("log"); + std::remove("test_check_converged_case1.log"); } // Test for check_converged when ucell.lc[0] == 1 && ucell.lc[1] == 1 && ucell.lc[2] == 1 && largest_grad == 0 @@ -259,7 +260,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase2) // Set up test data Lattice_Change_Basic::update_iter = 0; PARAM.input.stress_thr = 10.0; - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_check_converged_case2.log"); ucell.lc[0] = 1; ucell.lc[1] = 1; ucell.lc[2] = 1; @@ -274,11 +275,11 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase2) stress(2, 2) = 0.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad); - GlobalV::ofs_running.close(); + Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_check_converged_case2.log"); std::string expected_output = " Largest stress is 0, movement is impossible.\n"; std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(output, expected_output); @@ -287,7 +288,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase2) EXPECT_TRUE(Lattice_Change_Basic::converged); ifs.close(); - std::remove("log"); + std::remove("test_check_converged_case2.log"); } // Test for check_converged when ucell.lc[0] == 1 && ucell.lc[1] == 1 && ucell.lc[2] == 1, and converged @@ -296,7 +297,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase3) // Set up test data Lattice_Change_Basic::update_iter = 0; PARAM.input.stress_thr = 10.0; - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_check_converged_case3.log"); ucell.lc[0] = 1; ucell.lc[1] = 1; ucell.lc[2] = 1; @@ -311,11 +312,11 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase3) stress(2, 2) = 0.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad); - GlobalV::ofs_running.close(); + Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_check_converged_case3.log"); std::string expected_output = "\n Geometry relaxation is converged!\n\n Largest stress is 0.147105 kbar while threshold is 10 kbar\n"; std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(output, expected_output); @@ -324,7 +325,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase3) EXPECT_TRUE(Lattice_Change_Basic::converged); ifs.close(); - std::remove("log"); + std::remove("test_check_converged_case3.log"); } // Test for check_converged when ucell.lc != 1, but not converged @@ -333,7 +334,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase4) // Set up test data Lattice_Change_Basic::update_iter = 0; PARAM.input.stress_thr = 10.0; - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_check_converged_case4.log"); ucell.lc[0] = 0; ucell.lc[1] = 0; ucell.lc[2] = 0; @@ -348,11 +349,11 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase4) grad[8] = 1.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad); - GlobalV::ofs_running.close(); + Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_check_converged_case4.log"); std::string expected_output = "\n Geometry relaxation is not converged because threshold is 10 kbar\n"; std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(output, expected_output); @@ -361,7 +362,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase4) EXPECT_FALSE(Lattice_Change_Basic::converged); ifs.close(); - std::remove("log"); + std::remove("test_check_converged_case4.log"); } // Test for check_converged when ucell.lc != 1, and largest_grad == 0 @@ -370,7 +371,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase5) // Set up test data Lattice_Change_Basic::update_iter = 0; PARAM.input.stress_thr = 10.0; - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_check_converged_case5.log"); ucell.lc[0] = 0; ucell.lc[1] = 0; ucell.lc[2] = 0; @@ -385,11 +386,11 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase5) grad[8] = 0.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad); - GlobalV::ofs_running.close(); + Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_check_converged_case5.log"); std::string expected_output = " Largest stress is 0, movement is impossible.\n"; std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(output, expected_output); @@ -398,7 +399,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase5) EXPECT_TRUE(Lattice_Change_Basic::converged); ifs.close(); - std::remove("log"); + std::remove("test_check_converged_case5.log"); } // Test for check_converged when ucell.lc != 1, and converged @@ -407,7 +408,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase6) // Set up test data Lattice_Change_Basic::update_iter = 0; PARAM.input.stress_thr = 10.0; - GlobalV::ofs_running.open("log"); + std::ofstream ofs("test_check_converged_case6.log"); ucell.lc[0] = 0; ucell.lc[1] = 0; ucell.lc[2] = 0; @@ -422,11 +423,11 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase6) grad[8] = 0.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad); - GlobalV::ofs_running.close(); + Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + ofs.close(); // Check the results - std::ifstream ifs("log"); + std::ifstream ifs("test_check_converged_case6.log"); std::string expected_output = "\n Geometry relaxation is converged!\n\n Largest stress is 0.147105 kbar while threshold is 10 kbar\n"; std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(output, expected_output); @@ -435,7 +436,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase6) EXPECT_TRUE(Lattice_Change_Basic::converged); ifs.close(); - std::remove("log"); + std::remove("test_check_converged_case6.log"); } TEST_F(LatticeChangeBasicTest, TerminateConverged) @@ -447,16 +448,16 @@ TEST_F(LatticeChangeBasicTest, TerminateConverged) std::string expected_output = " end of lattice optimization\n stress_step = 5\n " " update iteration = 10\n"; - GlobalV::ofs_running.open("log"); - Lattice_Change_Basic::terminate(); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_terminate_converged.log"); + Lattice_Change_Basic::terminate(ofs); + ofs.close(); - std::ifstream ifs("log"); + std::ifstream ifs("test_terminate_converged.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(expected_output, output); ifs.close(); - std::remove("log"); + std::remove("test_terminate_converged.log"); } TEST_F(LatticeChangeBasicTest, TerminateNotConverged) @@ -465,16 +466,16 @@ TEST_F(LatticeChangeBasicTest, TerminateNotConverged) std::string expected_output = " the maximum number of steps has been reached.\n end of lattice optimization.\n"; - GlobalV::ofs_running.open("log"); - Lattice_Change_Basic::terminate(); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_terminate_not_converged.log"); + Lattice_Change_Basic::terminate(ofs); + ofs.close(); - std::ifstream ifs("log"); + std::ifstream ifs("test_terminate_not_converged.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(expected_output, output); ifs.close(); - std::remove("log"); + std::remove("test_terminate_not_converged.log"); } TEST_F(LatticeChangeBasicTest, SetupEtotStressStep1) diff --git a/source/source_relax/test/lattice_change_cg_test.cpp b/source/source_relax/test/lattice_change_cg_test.cpp index 11a320d3712..b559dd556ca 100644 --- a/source/source_relax/test/lattice_change_cg_test.cpp +++ b/source/source_relax/test/lattice_change_cg_test.cpp @@ -76,20 +76,20 @@ TEST_F(LatticeChangeCGTest, TestStartConverged) double etot = 0.0; // call function - GlobalV::ofs_running.open("log"); - lc_cg.start(ucell, stress, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_lc_cg_start_converged.log"); + lc_cg.start(ucell, stress, etot, ofs); + ofs.close(); // Check output std::string expected_output = " Largest stress is 0, movement is impossible.\n end of lattice optimization\n stress_step = 1\n " " update iteration = 5\n"; - std::ifstream ifs("log"); + std::ifstream ifs("test_lc_cg_start_converged.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(expected_output, output); ifs.close(); - std::remove("log"); + std::remove("test_lc_cg_start_converged.log"); } // Test function start() sd branch @@ -105,19 +105,19 @@ TEST_F(LatticeChangeCGTest, TestStartSd) double etot = 0.0; // call function - GlobalV::ofs_running.open("log"); - lc_cg.start(ucell, stress, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_lc_cg_start_sd.log"); + lc_cg.start(ucell, stress, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Geometry relaxation is not converged because threshold is 0.5 kbar\n"; - std::ifstream ifs("log"); + std::ifstream ifs("test_lc_cg_start_sd.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(expected_output, output); EXPECT_DOUBLE_EQ(Lattice_Change_Basic::lattice_change_ini, 0.01); ifs.close(); - std::remove("log"); + std::remove("test_lc_cg_start_sd.log"); } // Test function start() trial branch with goto @@ -134,22 +134,25 @@ TEST_F(LatticeChangeCGTest, TestStartTrialGoto) // call function lc_cg.move0[0] = 1.0; - lc_cg.start(ucell, stress, etot); + std::ofstream ofs1("test_lc_cg_start_trial_goto_temp1.log"); + lc_cg.start(ucell, stress, etot, ofs1); + ofs1.close(); + std::remove("test_lc_cg_start_trial_goto_temp1.log"); Lattice_Change_Basic::stress_step = 2; lc_cg.move0[0] = 10.0; - GlobalV::ofs_running.open("log"); - lc_cg.start(ucell, stress, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_lc_cg_start_trial_goto.log"); + lc_cg.start(ucell, stress, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Geometry relaxation is not converged because threshold is 0.5 kbar\n"; - std::ifstream ifs("log"); + std::ifstream ifs("test_lc_cg_start_trial_goto.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(expected_output, output); EXPECT_NEAR(Lattice_Change_Basic::lattice_change_ini, 10.000004999998749, 1e-12); ifs.close(); - std::remove("log"); + std::remove("test_lc_cg_start_trial_goto.log"); } // Test function start() trial branch without goto @@ -165,21 +168,24 @@ TEST_F(LatticeChangeCGTest, TestStartTrial) double etot = 0.0; // call function - lc_cg.start(ucell, stress, etot); + std::ofstream ofs1("test_lc_cg_start_trial_temp1.log"); + lc_cg.start(ucell, stress, etot, ofs1); + ofs1.close(); + std::remove("test_lc_cg_start_trial_temp1.log"); Lattice_Change_Basic::stress_step = 2; - GlobalV::ofs_running.open("log"); - lc_cg.start(ucell, stress, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs("test_lc_cg_start_trial.log"); + lc_cg.start(ucell, stress, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Geometry relaxation is not converged because threshold is 0.5 kbar\n"; - std::ifstream ifs("log"); + std::ifstream ifs("test_lc_cg_start_trial.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(expected_output, output); EXPECT_NEAR(Lattice_Change_Basic::lattice_change_ini, 70.000034999991243, 1e-12); ifs.close(); - std::remove("log"); + std::remove("test_lc_cg_start_trial.log"); } // Test function start() no trial branch with goto case 1 @@ -195,22 +201,28 @@ TEST_F(LatticeChangeCGTest, TestStartNoTrialGotoCase1) double etot = 0.0; // call function - lc_cg.start(ucell, stress, etot); + std::ofstream ofs1("test_lc_cg_start_notrial_goto_case1_temp1.log"); + lc_cg.start(ucell, stress, etot, ofs1); + ofs1.close(); + std::remove("test_lc_cg_start_notrial_goto_case1_temp1.log"); Lattice_Change_Basic::stress_step = 2; - lc_cg.start(ucell, stress, etot); - GlobalV::ofs_running.open("log"); - lc_cg.start(ucell, stress, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs2("test_lc_cg_start_notrial_goto_case1_temp2.log"); + lc_cg.start(ucell, stress, etot, ofs2); + ofs2.close(); + std::remove("test_lc_cg_start_notrial_goto_case1_temp2.log"); + std::ofstream ofs("test_lc_cg_start_notrial_goto_case1.log"); + lc_cg.start(ucell, stress, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Geometry relaxation is not converged because threshold is 0.5 kbar\n"; - std::ifstream ifs("log"); + std::ifstream ifs("test_lc_cg_start_notrial_goto_case1.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(expected_output, output); EXPECT_NEAR(Lattice_Change_Basic::lattice_change_ini, 490.00024499993867, 1e-12); ifs.close(); - std::remove("log"); + std::remove("test_lc_cg_start_notrial_goto_case1.log"); } // Test function start() no trial branch with goto case 2 @@ -227,24 +239,30 @@ TEST_F(LatticeChangeCGTest, TestStartNoTrialGotoCase2) // call function lc_cg.move0[0] = 0.1; - lc_cg.start(ucell, stress, etot); + std::ofstream ofs1("test_lc_cg_start_notrial_goto_case2_temp1.log"); + lc_cg.start(ucell, stress, etot, ofs1); + ofs1.close(); + std::remove("test_lc_cg_start_notrial_goto_case2_temp1.log"); Lattice_Change_Basic::stress_step = 2; - lc_cg.start(ucell, stress, etot); - GlobalV::ofs_running.open("log"); + std::ofstream ofs2("test_lc_cg_start_notrial_goto_case2_temp2.log"); + lc_cg.start(ucell, stress, etot, ofs2); + ofs2.close(); + std::remove("test_lc_cg_start_notrial_goto_case2_temp2.log"); + std::ofstream ofs("test_lc_cg_start_notrial_goto_case2.log"); lc_cg.move0[0] = 0.1; stress(0, 1) = 0.0001; - lc_cg.start(ucell, stress, etot); - GlobalV::ofs_running.close(); + lc_cg.start(ucell, stress, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Geometry relaxation is not converged because threshold is 0.5 kbar\n"; - std::ifstream ifs("log"); + std::ifstream ifs("test_lc_cg_start_notrial_goto_case2.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(expected_output, output); EXPECT_NEAR(Lattice_Change_Basic::lattice_change_ini, 3430.0017149995706, 1e-12); ifs.close(); - std::remove("log"); + std::remove("test_lc_cg_start_notrial_goto_case2.log"); } // Test function start() no trial branch without goto @@ -261,23 +279,29 @@ TEST_F(LatticeChangeCGTest, TestStartNoTrial) // call function lc_cg.move0[0] = 1.0; - lc_cg.start(ucell, stress, etot); + std::ofstream ofs1("test_lc_cg_start_notrial_temp1.log"); + lc_cg.start(ucell, stress, etot, ofs1); + ofs1.close(); + std::remove("test_lc_cg_start_notrial_temp1.log"); Lattice_Change_Basic::stress_step = 2; lc_cg.move0[0] = 10.0; - lc_cg.start(ucell, stress, etot); - GlobalV::ofs_running.open("log"); - lc_cg.start(ucell, stress, etot); - GlobalV::ofs_running.close(); + std::ofstream ofs2("test_lc_cg_start_notrial_temp2.log"); + lc_cg.start(ucell, stress, etot, ofs2); + ofs2.close(); + std::remove("test_lc_cg_start_notrial_temp2.log"); + std::ofstream ofs("test_lc_cg_start_notrial.log"); + lc_cg.start(ucell, stress, etot, ofs); + ofs.close(); // Check output std::string expected_output = "\n Geometry relaxation is not converged because threshold is 0.5 kbar\n"; - std::ifstream ifs("log"); + std::ifstream ifs("test_lc_cg_start_notrial.log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); EXPECT_EQ(expected_output, output); EXPECT_NEAR(Lattice_Change_Basic::lattice_change_ini, 96040.106328872833, 1e-12); ifs.close(); - std::remove("log"); + std::remove("test_lc_cg_start_notrial.log"); } // Test function setup_cg_grad() when ncggrad is multiple of 10000 diff --git a/source/source_relax/test/lattice_change_methods_test.cpp b/source/source_relax/test/lattice_change_methods_test.cpp index 69b95ac8922..d16c338a489 100644 --- a/source/source_relax/test/lattice_change_methods_test.cpp +++ b/source/source_relax/test/lattice_change_methods_test.cpp @@ -1,3 +1,4 @@ +#include #include "source_relax/lattice_change_methods.h" #include "mock_remake_cell.h" @@ -24,7 +25,7 @@ void Lattice_Change_CG::allocate(void) { } -void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in) +void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs) { } @@ -62,8 +63,9 @@ TEST_F(LatticeChangeMethodsTest, CalLatticeChange) ModuleBase::matrix stress(3, 3); double etot = 5.0; UnitCell ucell; + std::ofstream ofs("/dev/null"); - lcm.cal_lattice_change(istep, stress_step, stress, etot, ucell); + lcm.cal_lattice_change(istep, stress_step, stress, etot, ucell, ofs); // Assert that the static variables istep and stress_step are set correctly EXPECT_EQ(Lattice_Change_Basic::istep, istep); From 0071ad04661a0af4cc4dd6cefcfae88a0bbd824f Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Wed, 10 Jun 2026 08:51:28 +0800 Subject: [PATCH 19/50] fix bugs --- source/source_relax/ions_move_methods.cpp | 20 ++++++++----- source/source_relax/ions_move_methods.h | 2 +- source/source_relax/relax_nsync.cpp | 11 ++++--- .../source_relax/test/ions_move_bfgs_test.cpp | 30 ++++++++++++++++--- .../test/ions_move_methods_test.cpp | 29 ++++++++---------- 5 files changed, 59 insertions(+), 33 deletions(-) diff --git a/source/source_relax/ions_move_methods.cpp b/source/source_relax/ions_move_methods.cpp index d54f2b1b4c0..0547472f2d6 100644 --- a/source/source_relax/ions_move_methods.cpp +++ b/source/source_relax/ions_move_methods.cpp @@ -12,38 +12,42 @@ Ions_Move_Methods::~Ions_Move_Methods() { } -void Ions_Move_Methods::allocate(const int &natom) +void Ions_Move_Methods::allocate(const int &natom, const std::string& relax_method_0, const std::string& relax_method_1) { + if (natom <= 0) + { + ModuleBase::WARNING_QUIT("Ions_Move_Methods::allocate", "natom must be greater than 0."); + } Ions_Move_Basic::dim = natom * 3; - if (Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] != "1") + if (relax_method_0 == "bfgs" && relax_method_1 != "1") { this->bfgs.allocate(); } - else if (Ions_Move_Basic::relax_method[0] == "sd") + else if (relax_method_0 == "sd") { this->sd.allocate(); } - else if (Ions_Move_Basic::relax_method[0] == "cg") + else if (relax_method_0 == "cg") { this->cg.allocate(); } - else if (Ions_Move_Basic::relax_method[0] == "cg_bfgs") + else if (relax_method_0 == "cg_bfgs") { this->cg.allocate(); this->bfgs.allocate(); } - else if(Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] == "1") + else if(relax_method_0 == "bfgs" && relax_method_1 == "1") { this->bfgs_trad.allocate(natom); } - else if(Ions_Move_Basic::relax_method[0] == "lbfgs") + else if(relax_method_0 == "lbfgs") { this->lbfgs.allocate(natom); } else { - ModuleBase::WARNING("Ions_Move_Methods::init", "the parameter Ions_Move_Basic::relax_method is not correct."); + ModuleBase::WARNING("Ions_Move_Methods::init", "the parameter relax_method is not correct."); } return; } diff --git a/source/source_relax/ions_move_methods.h b/source/source_relax/ions_move_methods.h index a7b4ed84cc9..772eb4eb07d 100644 --- a/source/source_relax/ions_move_methods.h +++ b/source/source_relax/ions_move_methods.h @@ -16,7 +16,7 @@ class Ions_Move_Methods Ions_Move_Methods(); ~Ions_Move_Methods(); - void allocate(const int &natom); + void allocate(const int &natom, const std::string& relax_method_0, const std::string& relax_method_1); // void cal_movement(const int &istep, const ModuleBase::matrix &f, const double &etot); void cal_movement(const int &istep, const int &force_step, diff --git a/source/source_relax/relax_nsync.cpp b/source/source_relax/relax_nsync.cpp index 75c5c320c57..89165f491d2 100644 --- a/source/source_relax/relax_nsync.cpp +++ b/source/source_relax/relax_nsync.cpp @@ -10,12 +10,12 @@ void Relax_old::init_relax(const int& natom) if (PARAM.inp.calculation == "relax") { // Ions_Move_Methods - IMM.allocate(natom); + IMM.allocate(natom, PARAM.inp.relax_method[0], PARAM.inp.relax_method[1]); } if (PARAM.inp.calculation == "cell-relax") { // Ions_Move_Methods - IMM.allocate(natom); + IMM.allocate(natom, PARAM.inp.relax_method[0], PARAM.inp.relax_method[1]); // allocate arrays related to changes of lattice vectors LCM.allocate(); } @@ -41,10 +41,13 @@ bool Relax_old::relax_step(const int& istep, { return true; } + // choose what to do next - if (PARAM.inp.calculation != "cell-relax") { + if (PARAM.inp.calculation != "cell-relax") + { force_step = istep; -} + } + if (this->if_do_relax(ucell)) { // do relax calculation and generate next structure diff --git a/source/source_relax/test/ions_move_bfgs_test.cpp b/source/source_relax/test/ions_move_bfgs_test.cpp index 8ad773bbf55..01d8a06f241 100644 --- a/source/source_relax/test/ions_move_bfgs_test.cpp +++ b/source/source_relax/test/ions_move_bfgs_test.cpp @@ -91,6 +91,28 @@ TEST_F(IonsMoveBFGSTest, StartCase2) { // Initilize data UnitCell ucell; + // Initialize UnitCell with 2 atoms + ucell.ntype = 1; + ucell.nat = 2; + ucell.atoms = new Atom[ucell.ntype]; + ucell.atoms[0].na = 2; + ucell.atoms[0].tau = std::vector>(2); + ucell.atoms[0].taud = std::vector>(2); + ucell.atoms[0].mbl = std::vector>(2, {1, 1, 1}); + ucell.atoms[0].tau[0].x = 0.0; ucell.atoms[0].tau[0].y = 0.0; ucell.atoms[0].tau[0].z = 0.0; + ucell.atoms[0].tau[1].x = 1.0; ucell.atoms[0].tau[1].y = 0.0; ucell.atoms[0].tau[1].z = 0.0; + ucell.lat0 = 1.0; + ucell.set_atom_flag = true; + + // Initialize PARAM + PARAM.input.force_thr = 1.0e-3; + PARAM.input.force_thr_ev = PARAM.input.force_thr * 13.6058 / 0.529177; + PARAM.input.test_relax_method = 1; + PARAM.input.out_level = "ie"; + + // Initialize istep + Ions_Move_Basic::istep = 1; + ModuleBase::matrix force(2, 3); force(0, 0) = 10.0; double energy_in = 0.0; @@ -100,11 +122,8 @@ TEST_F(IonsMoveBFGSTest, StartCase2) // Call the function being tested bfgs.allocate(); std::ofstream ofs("test_start_case2.log"); - testing::internal::CaptureStderr(); - EXPECT_EXIT(bfgs.start(ucell, force, energy_in, ofs) , ::testing::ExitedWithCode(1), ""); - std::string stderr_output = testing::internal::GetCapturedStderr(); + bfgs.start(ucell, force, energy_in, ofs); ofs.close(); - std::remove("test_start_case2.log"); // Check the results std::ifstream ifs("test_start_case2.log"); @@ -113,6 +132,9 @@ TEST_F(IonsMoveBFGSTest, StartCase2) std::remove("test_start_case2.log"); EXPECT_THAT(output, testing::HasSubstr("Ion relaxation is not converged yet")); + + // Clean up + delete[] ucell.atoms; } // Test the restart_bfgs() function case 1 diff --git a/source/source_relax/test/ions_move_methods_test.cpp b/source/source_relax/test/ions_move_methods_test.cpp index 464377f643f..26a342eb0fe 100644 --- a/source/source_relax/test/ions_move_methods_test.cpp +++ b/source/source_relax/test/ions_move_methods_test.cpp @@ -98,34 +98,29 @@ class IonsMoveMethodsTest : public ::testing::Test // Test the allocate() function TEST_F(IonsMoveMethodsTest, Allocate) { - Ions_Move_Basic::relax_method[0] = "bfgs"; - imm.allocate(natom); + imm.allocate(natom, "bfgs", "1"); EXPECT_EQ(Ions_Move_Basic::dim, 6); - Ions_Move_Basic::relax_method[0] = "sd"; - imm.allocate(natom); + imm.allocate(natom, "sd", "1"); EXPECT_EQ(Ions_Move_Basic::dim, 6); - Ions_Move_Basic::relax_method[0] = "cg"; - imm.allocate(natom); + imm.allocate(natom, "cg", "1"); EXPECT_EQ(Ions_Move_Basic::dim, 6); - Ions_Move_Basic::relax_method[0] = "cg_bfgs"; - imm.allocate(natom); + imm.allocate(natom, "cg_bfgs", "1"); EXPECT_EQ(Ions_Move_Basic::dim, 6); } // Test the allocate() function warning quit TEST_F(IonsMoveMethodsTest, AllocateWarningQuit) { - Ions_Move_Basic::relax_method[0] = "none"; GlobalV::ofs_warning.open("log"); - imm.allocate(natom); + imm.allocate(natom, "none", "1"); GlobalV::ofs_warning.close(); std::ifstream ifs("log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); - EXPECT_THAT(output, testing::HasSubstr("the parameter Ions_Move_Basic::relax_method is not correct.")); + EXPECT_THAT(output, testing::HasSubstr("the parameter relax_method is not correct.")); ifs.close(); std::remove("log"); } @@ -140,22 +135,23 @@ TEST_F(IonsMoveMethodsTest, CalMovement) UnitCell ucell; Ions_Move_Basic::relax_method[0] = "bfgs"; - imm.allocate(natom); + Ions_Move_Basic::relax_method[1] = "1"; + imm.allocate(natom, "bfgs", "1"); imm.cal_movement(istep, force_step, f, etot, ucell); EXPECT_EQ(Ions_Move_Basic::istep, force_step); Ions_Move_Basic::relax_method[0] = "sd"; - imm.allocate(natom); + imm.allocate(natom, "sd", "1"); imm.cal_movement(istep, force_step, f, etot, ucell); EXPECT_EQ(Ions_Move_Basic::istep, force_step); Ions_Move_Basic::relax_method[0] = "cg"; - imm.allocate(natom); + imm.allocate(natom, "cg", "1"); imm.cal_movement(istep, force_step, f, etot, ucell); EXPECT_EQ(Ions_Move_Basic::istep, force_step); Ions_Move_Basic::relax_method[0] = "cg_bfgs"; - imm.allocate(natom); + imm.allocate(natom, "cg_bfgs", "1"); imm.cal_movement(istep, force_step, f, etot, ucell); EXPECT_EQ(Ions_Move_Basic::istep, force_step); } @@ -169,7 +165,8 @@ TEST_F(IonsMoveMethodsTest, CalMovementWarningQuit) const double etot = 0.0; UnitCell ucell; Ions_Move_Basic::relax_method[0] = "none"; - imm.allocate(natom); + Ions_Move_Basic::relax_method[1] = "1"; + imm.allocate(natom, "none", "1"); GlobalV::ofs_warning.open("log"); imm.cal_movement(istep, force_step, f, etot, ucell); From dc24a752c0b582224cf31d5003e41f450d145582 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Wed, 10 Jun 2026 08:58:15 +0800 Subject: [PATCH 20/50] update --- source/Makefile.Objects | 2 +- source/source_relax/CMakeLists.txt | 2 +- .../{lbfgs.cpp => ions_move_lbfgs.cpp} | 22 +++++++++---------- .../{lbfgs.h => ions_move_lbfgs.h} | 8 +++---- source/source_relax/ions_move_methods.h | 4 ++-- .../source_relax/test/ions_move_bfgs_test.cpp | 9 +++----- 6 files changed, 22 insertions(+), 25 deletions(-) rename source/source_relax/{lbfgs.cpp => ions_move_lbfgs.cpp} (90%) rename source/source_relax/{lbfgs.h => ions_move_lbfgs.h} (98%) diff --git a/source/Makefile.Objects b/source/Makefile.Objects index fc49ec2227a..10e55a464d3 100644 --- a/source/Makefile.Objects +++ b/source/Makefile.Objects @@ -475,7 +475,7 @@ OBJS_RELAXATION=relax_data.o\ lattice_change_methods.o\ relax_nsync.o\ relax_sync.o\ - lbfgs.o\ + ions_move_lbfgs.o\ matrix_methods.o\ line_search.o\ diff --git a/source/source_relax/CMakeLists.txt b/source/source_relax/CMakeLists.txt index 692e9315fb9..bce15417a9b 100644 --- a/source/source_relax/CMakeLists.txt +++ b/source/source_relax/CMakeLists.txt @@ -6,7 +6,7 @@ add_library( relax_driver.cpp relax_sync.cpp line_search.cpp - lbfgs.cpp + ions_move_lbfgs.cpp relax_nsync.cpp bfgs_basic.cpp ions_move_basic.cpp diff --git a/source/source_relax/lbfgs.cpp b/source/source_relax/ions_move_lbfgs.cpp similarity index 90% rename from source/source_relax/lbfgs.cpp rename to source/source_relax/ions_move_lbfgs.cpp index 9eb2c7ccda0..ae528f1eedd 100644 --- a/source/source_relax/lbfgs.cpp +++ b/source/source_relax/ions_move_lbfgs.cpp @@ -1,11 +1,11 @@ -#include "lbfgs.h" +#include "ions_move_lbfgs.h" #include "matrix_methods.h" #include "source_io/module_parameter/parameter.h" #include "ions_move_basic.h" #include "source_cell/update_cell.h" #include "source_cell/print_cell.h" // mohan add 2025-06-19 -void LBFGS::allocate(const int _size) // initialize H0、H、pos0、force0、force +void Ions_Move_LBFGS::allocate(const int _size) // initialize H0、H、pos0、force0、force { alpha=70;//default value in ase is 70 maxstep=PARAM.inp.relax_bfgs_rmax; @@ -25,7 +25,7 @@ void LBFGS::allocate(const int _size) // initialize H0、H、pos0、force0、for //l_search.init_line_search(); } -void LBFGS::relax_step(const ModuleBase::matrix _force,UnitCell& ucell,const double &etot) +void Ions_Move_LBFGS::relax_step(const ModuleBase::matrix _force,UnitCell& ucell,const double &etot) { get_pos(ucell,pos); @@ -68,7 +68,7 @@ void LBFGS::relax_step(const ModuleBase::matrix _force,UnitCell& ucell,const dou unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,GlobalV::ofs_running); } -void LBFGS::get_pos(UnitCell& ucell,std::vector>& pos) +void Ions_Move_LBFGS::get_pos(UnitCell& ucell,std::vector>& pos) { int k=0; for(int i=0;i>& po } } -void LBFGS::get_pos_taud(UnitCell& ucell,std::vector>& pos_taud) +void Ions_Move_LBFGS::get_pos_taud(UnitCell& ucell,std::vector>& pos_taud) { int k=0; for(int i=0;i } } -void LBFGS::prepare_step(std::vector>& force, +void Ions_Move_LBFGS::prepare_step(std::vector>& force, std::vector>& pos, std::vector>& H, std::vector& pos0, @@ -149,7 +149,7 @@ void LBFGS::prepare_step(std::vector>& force, pos_taud0=ReshapeMToV(pos_taud); force0 = changedforce; } -void LBFGS::update(std::vector>& pos_taud, +void Ions_Move_LBFGS::update(std::vector>& pos_taud, std::vector& pos_taud0, std::vector& force, std::vector& force0, @@ -221,7 +221,7 @@ void LBFGS::update(std::vector>& pos_taud, rho.erase(rho.begin()); } } -void LBFGS::determine_step(std::vector& steplength,std::vector>& dpos,double& maxstep) +void Ions_Move_LBFGS::determine_step(std::vector& steplength,std::vector>& dpos,double& maxstep) { std::vector::iterator maxsteplength = max_element(steplength.begin(), steplength.end()); double a = *maxsteplength; @@ -237,7 +237,7 @@ void LBFGS::determine_step(std::vector& steplength,std::vector grad= std::vector(3*size, 0.0); int iat = 0; diff --git a/source/source_relax/lbfgs.h b/source/source_relax/ions_move_lbfgs.h similarity index 98% rename from source/source_relax/lbfgs.h rename to source/source_relax/ions_move_lbfgs.h index b931b528415..c081a8e9a34 100644 --- a/source/source_relax/lbfgs.h +++ b/source/source_relax/ions_move_lbfgs.h @@ -1,5 +1,5 @@ -#ifndef LBFGS_H -#define LBFGS_H +#ifndef IONS_MOVE_LBFGS_H +#define IONS_MOVE_LBFGS_H #include #include @@ -13,10 +13,10 @@ #include "source_esolver/esolver_ks.h" /** - * @class LBFGS + * @class Ions_Move_LBFGS * @brief Implements L-BFGS optimization algorithm for structural relaxation */ -class LBFGS +class Ions_Move_LBFGS { public: /** diff --git a/source/source_relax/ions_move_methods.h b/source/source_relax/ions_move_methods.h index 772eb4eb07d..ee8c15eae45 100644 --- a/source/source_relax/ions_move_methods.h +++ b/source/source_relax/ions_move_methods.h @@ -8,7 +8,7 @@ #include "ions_move_cg.h" #include "ions_move_sd.h" #include "ions_move_bfgs2.h" -#include "lbfgs.h" +#include "ions_move_lbfgs.h" class Ions_Move_Methods { @@ -51,6 +51,6 @@ class Ions_Move_Methods Ions_Move_CG cg; Ions_Move_SD sd; Ions_Move_BFGS2 bfgs_trad; - LBFGS lbfgs; + Ions_Move_LBFGS lbfgs; }; #endif diff --git a/source/source_relax/test/ions_move_bfgs_test.cpp b/source/source_relax/test/ions_move_bfgs_test.cpp index 01d8a06f241..2f8f3cbb549 100644 --- a/source/source_relax/test/ions_move_bfgs_test.cpp +++ b/source/source_relax/test/ions_move_bfgs_test.cpp @@ -255,8 +255,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase1) std::string expected_ofs = " dE0s = 0\n den = 0.1\n " " interpolated trust radius = 0\ntrust_radius = 0\nrelax_bfgs_rmin = 1\nrelax_bfgs_rmax = -1\n " - "trust_radius < relax_bfgs_rmin, reset bfgs history.\n istep = 0\n " - " update iteration = 0\n"; + "trust_radius < relax_bfgs_rmin, reset bfgs history.\n"; std::string expected_std = " BFGS TRUST (Bohr) : 1\n"; EXPECT_THAT(ofs_output, ::testing::HasSubstr(expected_ofs)); @@ -318,8 +317,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase2) ifs.close(); std::remove("test_bfgs_routine_case2.log"); - std::string expected_ofs = " quadratic interpolation is impossible.\n istep = " - "0\n update iteration = 0\n"; + std::string expected_ofs = " quadratic interpolation is impossible.\n"; std::string expected_std = ""; EXPECT_THAT(ofs_output, ::testing::HasSubstr(expected_ofs)); @@ -377,8 +375,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase3) ifs.close(); std::remove("test_bfgs_routine_case3.log"); - std::string expected_ofs = " check the norm of new move 410 (Bohr)\n Uphill move : resetting bfgs history\n " - " istep = 0\n update iteration = 1\n"; + std::string expected_ofs = " check the norm of new move 410 (Bohr)\n Uphill move : resetting bfgs history\n"; EXPECT_THAT(ofs_output, ::testing::HasSubstr(expected_ofs)); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, 0.2); From 5f409814bf382dc2a24c64655fa4d55ae84e2ca7 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Wed, 10 Jun 2026 09:02:55 +0800 Subject: [PATCH 21/50] remove esolver_ks.h --- source/source_relax/relax_driver.h | 1 - 1 file changed, 1 deletion(-) diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index 2c970e3a451..27c2ec8d857 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -3,7 +3,6 @@ #include "source_cell/unitcell.h" #include "source_esolver/esolver.h" -#include "source_esolver/esolver_ks.h" #include "relax_sync.h" #include "relax_nsync.h" #include "ions_move_bfgs2.h" From 31ba7ede309f51a400e6c752c98ab9d148406f00 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Wed, 10 Jun 2026 09:34:18 +0800 Subject: [PATCH 22/50] fix a bug --- source/source_relax/lattice_change_basic.h | 2 +- source/source_relax/relax_data.cpp | 1 + source/source_relax/relax_data.h | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/source_relax/lattice_change_basic.h b/source/source_relax/lattice_change_basic.h index 40440a2745b..ec2eb9a8521 100644 --- a/source/source_relax/lattice_change_basic.h +++ b/source/source_relax/lattice_change_basic.h @@ -17,7 +17,7 @@ namespace Lattice_Change_Basic { // Shared state variables (referenced from Relax_Data for unified data sharing) -static int& dim = Relax_Data::dim; ///< Dimension of free variables (9 for full lattice) +static int& dim = Relax_Data::dim_lattice; ///< Dimension of free variables (9 for full lattice) static bool& converged = Relax_Data::converged; ///< Convergence flag static double& largest_grad = Relax_Data::largest_grad; ///< Largest gradient component static int& istep = Relax_Data::istep; ///< Current ionic step index diff --git a/source/source_relax/relax_data.cpp b/source/source_relax/relax_data.cpp index 54c4e1a118f..98da0ce56a3 100644 --- a/source/source_relax/relax_data.cpp +++ b/source/source_relax/relax_data.cpp @@ -1,6 +1,7 @@ #include "relax_data.h" int Relax_Data::dim = 0; +int Relax_Data::dim_lattice = 0; bool Relax_Data::converged = false; double Relax_Data::largest_grad = 0.0; int Relax_Data::istep = 0; diff --git a/source/source_relax/relax_data.h b/source/source_relax/relax_data.h index 23caa55606e..2894a781adc 100644 --- a/source/source_relax/relax_data.h +++ b/source/source_relax/relax_data.h @@ -30,7 +30,8 @@ class Relax_Data { void allocate(const int dim_in); // Static members - shared global state across all relaxation instances - static int dim; ///< Dimension of free variables (3 * number of atoms) + static int dim; ///< Dimension of free variables (3 * number of atoms) for ion movement + static int dim_lattice; ///< Dimension of free variables (9) for lattice change static bool converged; ///< Convergence flag: true if optimization is converged static double largest_grad; ///< Largest gradient component (force) in current step static int istep; ///< Current iteration step index From f9282160b84caa0f67e95b503db88d0b46a20468 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Wed, 10 Jun 2026 12:51:37 +0800 Subject: [PATCH 23/50] delete useless variable --- source/source_relax/line_search.cpp | 1 - source/source_relax/relax_driver.h | 3 --- 2 files changed, 4 deletions(-) diff --git a/source/source_relax/line_search.cpp b/source/source_relax/line_search.cpp index db5a049382b..70ccc54956c 100644 --- a/source/source_relax/line_search.cpp +++ b/source/source_relax/line_search.cpp @@ -398,7 +398,6 @@ bool Line_Search::brent(const double x, const double y, const double f, double& { GlobalV::ofs_running << "Too many Brent steps, let's do next CG step" << std::endl; return true; - // ModuleBase::WARNING_QUIT("Brent","too many steps in line search, something wrong"); } return false; } // end ibrack diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index 27c2ec8d857..7a0e5b7adb1 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -5,7 +5,6 @@ #include "source_esolver/esolver.h" #include "relax_sync.h" #include "relax_nsync.h" -#include "ions_move_bfgs2.h" #include "source_io/module_parameter/input_parameter.h" class Relax_Driver @@ -31,8 +30,6 @@ class Relax_Driver // old relaxation method Relax_old rl_old; - Ions_Move_BFGS2 bfgs_trad; - }; From 5f504b57bdbde8c673b58195299e028b58e2963a Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Wed, 10 Jun 2026 16:15:40 +0800 Subject: [PATCH 24/50] =?UTF-8?q?refactor(relax=5Fdriver):=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=BC=9B=E8=B1=AB=E9=A9=B1=E5=8A=A8=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要修改: 1. 移除了 relax_driver.h 中未使用的 Ions_Move_BFGS2 bfgs_trad 成员变量及其头文件包含 2. 将 relax_driver.cpp 中 while 循环内的逻辑拆分为多个独立函数: - init_relax(): 初始化弛豫方法 - iter_info(): 打印迭代信息 - esolve(): 电子结构计算 - relax_step(): 执行单次弛豫步骤 - stru_out(): 输出结构文件 - json_out(): 输出 JSON 结果 - stop_cond(): 检查停止条件 - final_out(): 最终输出 3. 添加了成员变量用于缓存计算结果:force_, stress_, force_step, stress_step 4. 优化了 final_out() 函数,将重复的条件判断合并为早期返回 5. 所有成员变量和成员函数调用都添加了 this-> 前缀,提高代码可读性 --- source/source_relax/relax_driver.cpp | 315 +++++++++++++-------------- source/source_relax/relax_driver.h | 20 +- 2 files changed, 169 insertions(+), 166 deletions(-) diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index 82d96b7b9dd..a5ecdb9aabe 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -17,189 +17,191 @@ void Relax_Driver::relax_driver( ModuleBase::TITLE("Relax_Driver", "relax_driver"); ModuleBase::timer::start("Relax_Driver", "relax_driver"); - if (inp.calculation == "relax" || inp.calculation == "cell-relax" ) + this->init_relax(ucell.nat, inp); + + this->istep = 1; + bool stop = false; + + while (this->istep <= inp.relax_nmax && !stop) + { + this->iter_info(inp); + this->esolve(p_esolver, ucell); + stop = this->relax_step(p_esolver, ucell, inp); + this->json_out(p_esolver, ucell, inp); + stop = this->stop_cond(stop); + ++this->istep; + } + + this->final_out(ucell, inp); + + ModuleBase::timer::end("Relax_Driver", "relax_driver"); + return; +} + +void Relax_Driver::init_relax(const int nat, const Input_para& inp) +{ + if (inp.calculation == "relax" || inp.calculation == "cell-relax") { - if (!inp.relax_new) // traditional relax + if (!inp.relax_new) { - rl_old.init_relax(ucell.nat); + this->rl_old.init_relax(nat); } - else // relax new + else { - rl.init_relax(ucell.nat); + this->rl.init_relax(nat); } } +} - this->istep = 1; - int force_step = 1; - int stress_step = 1; - bool stop = false; - - while (istep <= inp.relax_nmax && !stop) +void Relax_Driver::iter_info(const Input_para& inp) +{ + if (inp.out_level == "ie" + && (inp.calculation == "relax" + || inp.calculation == "cell-relax" + || inp.calculation == "scf" + || inp.calculation == "nscf") + && (inp.esolver_type != "lr")) { - time_t estart = time(nullptr); - - if (inp.out_level == "ie" - && (inp.calculation == "relax" - || inp.calculation == "cell-relax" - || inp.calculation == "scf" - || inp.calculation == "nscf") - && (inp.esolver_type != "lr")) - { - ModuleIO::print_screen(stress_step, force_step, istep); - } + ModuleIO::print_screen(this->stress_step, this->force_step, this->istep); + } #ifdef __RAPIDJSON - Json::init_output_array_obj(); -#endif //__RAPIDJSON - - // mohan added eiter to count for the electron iteration number, 2021-01-28 - p_esolver->runner(ucell, istep - 1); + Json::init_output_array_obj(); +#endif +} - time_t eend = time(nullptr); - time_t fstart = time(nullptr); - ModuleBase::matrix force; - ModuleBase::matrix stress; +void Relax_Driver::esolve(ModuleESolver::ESolver* p_esolver, UnitCell& ucell) +{ + p_esolver->runner(ucell, this->istep - 1); - // I'm considering putting force and stress - // as part of ucell and use ucell to pass information - // back and forth between esolver and relaxation - // but I'll use force and stress explicitly here for now + this->etot = p_esolver->cal_energy(); - // calculate the total energy - this->etot = p_esolver->cal_energy(); + if (PARAM.inp.cal_force) + { + p_esolver->cal_force(ucell, this->force_); + } - // calculate and gather all parts of total ionic forces - if (inp.cal_force) - { - p_esolver->cal_force(ucell, force); - } - else - { - // do nothing - } + if (PARAM.inp.cal_stress) + { + p_esolver->cal_stress(ucell, this->stress_); + } +} +bool Relax_Driver::relax_step(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp) +{ + if (inp.calculation != "relax" && inp.calculation != "cell-relax") + { + return false; + } - // calculate and gather all parts of stress - if (inp.cal_stress) - { - p_esolver->cal_stress(ucell, stress); - } - else - { - // do nothing - } + bool stop = false; - if (inp.calculation == "relax" || inp.calculation == "cell-relax") - { - if (inp.relax_new) - { - stop = rl.relax_step(ucell, force, stress, this->etot); - // mohan added 2025-07-14 - stress_step = istep+1; - force_step = 1; - } - else - { - stop = rl_old.relax_step(istep, - this->etot, - ucell, - force, - stress, - force_step, - stress_step); - } - - bool need_orb = inp.basis_type == "pw"; - need_orb = need_orb && inp.init_wfc.substr(0, 3) == "nao"; - need_orb = need_orb || inp.basis_type == "lcao"; - need_orb = need_orb || inp.basis_type == "lcao_in_pw"; - - std::stringstream ss, ss1; - ss << PARAM.globalv.global_out_dir << "STRU_ION_D"; - - unitcell::print_stru_file(ucell, - ucell.atoms, - ucell.latvec, - ss.str(), - inp.nspin, - true, - inp.calculation == "md", - inp.out_mul, - need_orb, - PARAM.globalv.deepks_setorb, - GlobalV::MY_RANK); - - if (Ions_Move_Basic::out_stru) - { - ss1 << PARAM.globalv.global_out_dir << "STRU_ION"; - ss1 << istep << "_D"; - unitcell::print_stru_file(ucell, - ucell.atoms, - ucell.latvec, - ss1.str(), - inp.nspin, - true, - inp.calculation == "md", - inp.out_mul, - need_orb, - PARAM.globalv.deepks_setorb, - GlobalV::MY_RANK); - ModuleIO::CifParser::write(PARAM.globalv.global_out_dir + "STRU_NOW.cif", - ucell, - "# Generated by ABACUS ModuleIO::CifParser", - "data_?"); - } - - ModuleIO::output_after_relax(stop, p_esolver->conv_esolver, GlobalV::ofs_running); - }// end relax or cell_relax + if (inp.relax_new) + { + stop = this->rl.relax_step(ucell, this->force_, this->stress_, this->etot); + this->stress_step = this->istep + 1; + this->force_step = 1; + } + else + { + stop = this->rl_old.relax_step(this->istep, this->etot, ucell, this->force_, this->stress_, this->force_step, this->stress_step); + } -#ifdef __RAPIDJSON - // add the energy to outout - Json::add_output_energy(p_esolver->cal_energy() * ModuleBase::Ry_to_eV); - // add Json of cell coo stress force - double unit_transform = ModuleBase::RYDBERG_SI / pow(ModuleBase::BOHR_RADIUS_SI, 3) * 1.0e-8; - double fac = ModuleBase::Ry_to_eV / 0.529177; - Json::add_output_cell_coo_stress_force(&ucell, force, fac, stress, unit_transform); -#endif //__RAPIDJSON - - if (stop == false) - { - stop = ModuleIO::read_exit_file(GlobalV::MY_RANK, "EXIT", GlobalV::ofs_running); - } + this->stru_out(ucell, inp); - time_t fend = time(nullptr); + ModuleIO::output_after_relax(stop, p_esolver->conv_esolver, GlobalV::ofs_running); - ++istep; - } // end while (istep <= inp.relax_nmax && !stop) + return stop; +} - // output the final relaxed structure in CIF format - if (inp.calculation == "relax" || inp.calculation == "cell-relax") +void Relax_Driver::stru_out(UnitCell& ucell, const Input_para& inp) +{ + bool need_orb = inp.basis_type == "pw"; + need_orb = need_orb && inp.init_wfc.substr(0, 3) == "nao"; + need_orb = need_orb || inp.basis_type == "lcao"; + need_orb = need_orb || inp.basis_type == "lcao_in_pw"; + + std::stringstream ss, ss1; + ss << PARAM.globalv.global_out_dir << "STRU_ION_D"; + + unitcell::print_stru_file(ucell, + ucell.atoms, + ucell.latvec, + ss.str(), + inp.nspin, + true, + inp.calculation == "md", + inp.out_mul, + need_orb, + PARAM.globalv.deepks_setorb, + GlobalV::MY_RANK); + + if (Ions_Move_Basic::out_stru) { - ModuleIO::CifParser::write(PARAM.globalv.global_out_dir + "STRU_FINAL.cif", + ss1 << PARAM.globalv.global_out_dir << "STRU_ION"; + ss1 << this->istep << "_D"; + unitcell::print_stru_file(ucell, + ucell.atoms, + ucell.latvec, + ss1.str(), + inp.nspin, + true, + inp.calculation == "md", + inp.out_mul, + need_orb, + PARAM.globalv.deepks_setorb, + GlobalV::MY_RANK); + ModuleIO::CifParser::write(PARAM.globalv.global_out_dir + "STRU_NOW.cif", ucell, "# Generated by ABACUS ModuleIO::CifParser", "data_?"); } +} - if (inp.calculation == "relax" || inp.calculation == "cell-relax") +void Relax_Driver::json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp) +{ +#ifdef __RAPIDJSON + Json::add_output_energy(p_esolver->cal_energy() * ModuleBase::Ry_to_eV); + + double unit_transform = ModuleBase::RYDBERG_SI / pow(ModuleBase::BOHR_RADIUS_SI, 3) * 1.0e-8; + double fac = ModuleBase::Ry_to_eV / 0.529177; + Json::add_output_cell_coo_stress_force(&ucell, this->force_, fac, this->stress_, unit_transform); +#endif +} + +bool Relax_Driver::stop_cond(bool stop) +{ + if (stop == false) { - if (istep-1 == inp.relax_nmax) - { - std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; - std::cout << " Geometry relaxation stops here due to reaching the maximum " << std::endl; - std::cout << " relaxation steps. More steps are needed to converge the results " << std::endl; - std::cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; - } - else - { - std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; - std::cout << " Geometry relaxation thresholds are reached within " << istep-1 << " steps." << std::endl; - std::cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; - } + stop = ModuleIO::read_exit_file(GlobalV::MY_RANK, "EXIT", GlobalV::ofs_running); + } + return stop; +} + +void Relax_Driver::final_out(UnitCell& ucell, const Input_para& inp) +{ + if (inp.calculation != "relax" && inp.calculation != "cell-relax") + { + return; + } + + ModuleIO::CifParser::write(PARAM.globalv.global_out_dir + "STRU_FINAL.cif", + ucell, + "# Generated by ABACUS ModuleIO::CifParser", + "data_?"); + + if (this->istep - 1 == inp.relax_nmax) + { + std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; + std::cout << " Geometry relaxation stops here due to reaching the maximum " << std::endl; + std::cout << " relaxation steps. More steps are needed to converge the results " << std::endl; + std::cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; } else { - // do nothing + std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; + std::cout << " Geometry relaxation thresholds are reached within " << this->istep - 1 << " steps." << std::endl; + std::cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; } if (inp.relax_nmax == 0) @@ -208,11 +210,4 @@ void Relax_Driver::relax_driver( std::cout << " relax_nmax = 0, DRY RUN TEST SUCCEEDS :)" << std::endl; std::cout << "-----------------------------------------------" << std::endl; } - else - { - // do nothing - } - - ModuleBase::timer::end("Relax_Driver", "relax_driver"); - return; -} +} \ No newline at end of file diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index 7a0e5b7adb1..4153ce042ca 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -6,6 +6,7 @@ #include "relax_sync.h" #include "relax_nsync.h" #include "source_io/module_parameter/input_parameter.h" +#include "source_base/matrix.h" class Relax_Driver { @@ -19,18 +20,25 @@ class Relax_Driver const Input_para& inp); private: - // mohan add 2021-01-28 - // mohan moved this variable from electrons.h to relax_driver.h int istep = 0; double etot = 0; + int force_step = 1; + int stress_step = 1; - // new relaxation method - Relax rl; + ModuleBase::matrix force_; + ModuleBase::matrix stress_; - // old relaxation method + Relax rl; Relax_old rl_old; - + void init_relax(const int nat, const Input_para& inp); + void iter_info(const Input_para& inp); + void esolve(ModuleESolver::ESolver* p_esolver, UnitCell& ucell); + bool relax_step(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp); + void stru_out(UnitCell& ucell, const Input_para& inp); + void json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp); + bool stop_cond(bool stop); + void final_out(UnitCell& ucell, const Input_para& inp); }; #endif From 110cd92d891cecad2e80724d4b5a40dbcc2fef56 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 11 Jun 2026 14:21:02 +0800 Subject: [PATCH 25/50] update --- source/source_relax/relax_sync.cpp | 42 ++++++++---------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/source/source_relax/relax_sync.cpp b/source/source_relax/relax_sync.cpp index 492feaea497..ea6f5f5d866 100644 --- a/source/source_relax/relax_sync.cpp +++ b/source/source_relax/relax_sync.cpp @@ -193,48 +193,28 @@ bool Relax::setup_gradient(const UnitCell& ucell, const ModuleBase::matrix& forc { // Note stress is given in the directions of lattice vectors // So we need to first convert to Cartesian and then apply the constraint - ModuleBase::Matrix3 stress_cart; - stress_cart.e11 = stress_ev(0, 0); - stress_cart.e12 = stress_ev(0, 1); - stress_cart.e13 = stress_ev(0, 2); - stress_cart.e21 = stress_ev(1, 0); - stress_cart.e22 = stress_ev(1, 1); - stress_cart.e23 = stress_ev(1, 2); - stress_cart.e31 = stress_ev(2, 0); - stress_cart.e32 = stress_ev(2, 1); - stress_cart.e33 = stress_ev(2, 2); - - stress_cart = ucell.latvec * stress_cart; + ModuleBase::matrix stress_cart = ucell.latvec.to_matrix() * stress_ev; if (ucell.lc[0] == 0) { - stress_cart.e11 = 0; - stress_cart.e12 = 0; - stress_cart.e13 = 0; + stress_cart(0, 0) = 0; + stress_cart(0, 1) = 0; + stress_cart(0, 2) = 0; } if (ucell.lc[1] == 0) { - stress_cart.e21 = 0; - stress_cart.e22 = 0; - stress_cart.e23 = 0; + stress_cart(1, 0) = 0; + stress_cart(1, 1) = 0; + stress_cart(1, 2) = 0; } if (ucell.lc[2] == 0) { - stress_cart.e31 = 0; - stress_cart.e32 = 0; - stress_cart.e33 = 0; + stress_cart(2, 0) = 0; + stress_cart(2, 1) = 0; + stress_cart(2, 2) = 0; } - stress_cart = ucell.GT * stress_cart; - stress_ev(0, 0) = stress_cart.e11; - stress_ev(0, 1) = stress_cart.e12; - stress_ev(0, 2) = stress_cart.e13; - stress_ev(1, 0) = stress_cart.e21; - stress_ev(1, 1) = stress_cart.e22; - stress_ev(1, 2) = stress_cart.e23; - stress_ev(2, 0) = stress_cart.e31; - stress_ev(2, 1) = stress_cart.e32; - stress_ev(2, 2) = stress_cart.e33; + stress_ev = ucell.GT.to_matrix() * stress_cart; } for (int i = 0; i < 3; i++) From cd55cde948cff7c289c173760e03b6e4b22dd458 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 11 Jun 2026 16:04:13 +0800 Subject: [PATCH 26/50] change name --- source/source_relax/relax_driver.h | 2 +- source/source_relax/relax_nsync.cpp | 113 +++++++++++----------------- source/source_relax/relax_nsync.h | 5 +- 3 files changed, 44 insertions(+), 76 deletions(-) diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index 4153ce042ca..dfc0e1cb333 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -29,7 +29,7 @@ class Relax_Driver ModuleBase::matrix stress_; Relax rl; - Relax_old rl_old; + IonCellOptimizer rl_old; void init_relax(const int nat, const Input_para& inp); void iter_info(const Input_para& inp); diff --git a/source/source_relax/relax_nsync.cpp b/source/source_relax/relax_nsync.cpp index 89165f491d2..6d48fa2b6c0 100644 --- a/source/source_relax/relax_nsync.cpp +++ b/source/source_relax/relax_nsync.cpp @@ -1,10 +1,10 @@ #include "relax_nsync.h" - #include "source_base/global_function.h" #include "source_base/global_variable.h" #include "source_io/module_parameter/parameter.h" #include "source_cell/update_cell.h" -void Relax_old::init_relax(const int& natom) + +void IonCellOptimizer::init_relax(const int& natom) { // Geometry optimization algorithm setup. if (PARAM.inp.calculation == "relax") @@ -22,7 +22,7 @@ void Relax_old::init_relax(const int& natom) } // The interface for relaxation -bool Relax_old::relax_step(const int& istep, +bool IonCellOptimizer::relax_step(const int& istep, const double& energy, UnitCell& ucell, ModuleBase::matrix force, @@ -30,124 +30,95 @@ bool Relax_old::relax_step(const int& istep, int& force_step, int& stress_step) { - ModuleBase::TITLE("Relax_old", "relax_step"); + ModuleBase::TITLE("IonCellOptimizer", "relax_step"); - // should not do it this way, will change after the refactor of ucell class ucell.ionic_position_updated = false; ucell.cell_parameter_updated = false; - // stop in last step if (istep == PARAM.inp.relax_nmax) { return true; } - // choose what to do next - if (PARAM.inp.calculation != "cell-relax") + const bool is_cell_relax = (PARAM.inp.calculation == "cell-relax"); + const bool is_relax = (PARAM.inp.calculation == "relax"); + + if (!is_cell_relax) { force_step = istep; } - if (this->if_do_relax(ucell)) + const bool need_atom_relax = (is_relax || is_cell_relax) && ucell.if_atoms_can_move(); + const bool need_cell_relax = is_cell_relax && ucell.if_cell_can_change(); + + if (need_atom_relax) { - // do relax calculation and generate next structure - bool converged = false; - converged = this->do_relax(istep, force, energy, ucell, force_step, GlobalV::ofs_running); + assert(PARAM.inp.cal_force == 1); + bool converged = this->do_relax(istep, force, energy, ucell, force_step, GlobalV::ofs_running); if (!converged) { ucell.ionic_position_updated = true; - return converged; + return false; } - else if (PARAM.inp.calculation != "cell-relax") + else if (!is_cell_relax) { - return converged; + return true; } } - if (this->if_do_cellrelax(ucell)) + else if (is_relax) { - // do cell relax calculation and generate next structure - bool converged = false; - converged = this->do_cellrelax(istep, stress_step, stress, energy, ucell, GlobalV::ofs_running); - if (!converged) - { - force_step = 1; - stress_step++; - ucell.cell_parameter_updated = true; - unitcell::setup_cell_after_vc(ucell,GlobalV::ofs_running); - ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SETUP UNITCELL"); - } - return converged; + ModuleBase::WARNING("IonCellOptimizer", "No atom is allowed to move!"); + return true; } - return true; -} - -bool Relax_old::if_do_relax(const UnitCell& ucell) -{ - ModuleBase::TITLE("Relax_old", "if_do_relax"); - if (PARAM.inp.calculation == "relax" || PARAM.inp.calculation == "cell-relax") + if (need_cell_relax) { - if (!ucell.if_atoms_can_move()) + if (ucell.if_atoms_can_move() && !IMM.get_converged()) { - ModuleBase::WARNING("Ions", "No atom is allowed to move!"); + GlobalV::ofs_running << "Note: Need to wait for atomic relaxation first!" << std::endl; return false; } - // if(!IMM.get_converged()) return 1; - else + + assert(PARAM.inp.cal_stress == 1); + bool converged = this->do_cellrelax(istep, stress_step, stress, energy, ucell, GlobalV::ofs_running); + if (!converged) { - assert(PARAM.inp.cal_force == 1); - return true; + force_step = 1; + stress_step++; + ucell.cell_parameter_updated = true; + unitcell::setup_cell_after_vc(ucell, GlobalV::ofs_running); + ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SETUP UNITCELL"); } + return converged; } - else { - return false; -} -} -bool Relax_old::if_do_cellrelax(const UnitCell& ucell) -{ - ModuleBase::TITLE("Relax_old", "if_do_cellrelax"); - if (PARAM.inp.calculation == "cell-relax") + else if (is_cell_relax) { - if (!ucell.if_cell_can_change()) - { - ModuleBase::WARNING("Ions", "Lattice vectors are not allowed to change!"); - return false; - } - else if (ucell.if_atoms_can_move() && !IMM.get_converged()) - { - GlobalV::ofs_running << "Note: Need to wait for atomic relaxation first!"; - return false; - } - else - { - assert(PARAM.inp.cal_stress == 1); - return true; - } + ModuleBase::WARNING("IonCellOptimizer", "Lattice vectors are not allowed to change!"); + return true; } - else { - return false; -} + + return true; } -bool Relax_old::do_relax(const int& istep, +bool IonCellOptimizer::do_relax(const int& istep, const ModuleBase::matrix& ionic_force, const double& total_energy, UnitCell& ucell, int& jstep, std::ofstream& ofs) { - ModuleBase::TITLE("Relax_old", "do_relax"); + ModuleBase::TITLE("IonCellOptimizer", "do_relax"); IMM.cal_movement(istep, jstep, ionic_force, total_energy, ucell, ofs); ++jstep; return IMM.get_converged(); } -bool Relax_old::do_cellrelax(const int& istep, +bool IonCellOptimizer::do_cellrelax(const int& istep, const int& stress_step, const ModuleBase::matrix& stress, const double& total_energy, UnitCell& ucell, std::ofstream& ofs) { - ModuleBase::TITLE("Relax_old", "do_cellrelax"); + ModuleBase::TITLE("IonCellOptimizer", "do_cellrelax"); LCM.cal_lattice_change(istep, stress_step, stress, total_energy, ucell, ofs); return LCM.get_converged(); } diff --git a/source/source_relax/relax_nsync.h b/source/source_relax/relax_nsync.h index c87fd15cada..3668519c0a6 100644 --- a/source/source_relax/relax_nsync.h +++ b/source/source_relax/relax_nsync.h @@ -6,7 +6,7 @@ #include "lattice_change_methods.h" #include "source_cell/unitcell.h" -class Relax_old +class IonCellOptimizer { public: void init_relax(const int& natom); @@ -22,9 +22,6 @@ class Relax_old Ions_Move_Methods IMM; Lattice_Change_Methods LCM; - // seperate force_stress function first - bool if_do_relax(const UnitCell& ucell); - bool if_do_cellrelax(const UnitCell& ucell); bool do_relax(const int& istep, const ModuleBase::matrix& ionic_force, const double& total_energy, From cda29ce1915afd3c29f1bb949253a41bdea69c0d Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 11 Jun 2026 16:23:06 +0800 Subject: [PATCH 27/50] update --- source/source_relax/relax_nsync.cpp | 90 +++++++++++++++++++---------- source/source_relax/relax_nsync.h | 56 ++++++++++++------ 2 files changed, 98 insertions(+), 48 deletions(-) diff --git a/source/source_relax/relax_nsync.cpp b/source/source_relax/relax_nsync.cpp index 6d48fa2b6c0..fb3c46d1e82 100644 --- a/source/source_relax/relax_nsync.cpp +++ b/source/source_relax/relax_nsync.cpp @@ -4,24 +4,51 @@ #include "source_io/module_parameter/parameter.h" #include "source_cell/update_cell.h" +/** + * @brief Initialize relaxation algorithms based on calculation type. + * + * Allocates memory and initializes the appropriate relaxation methods: + * - For "relax" calculation: only initializes Ions_Move_Methods + * - For "cell-relax" calculation: initializes both Ions_Move_Methods and + * Lattice_Change_Methods + * + * @param natom Number of atoms in the system + */ void IonCellOptimizer::init_relax(const int& natom) { - // Geometry optimization algorithm setup. if (PARAM.inp.calculation == "relax") { - // Ions_Move_Methods IMM.allocate(natom, PARAM.inp.relax_method[0], PARAM.inp.relax_method[1]); } if (PARAM.inp.calculation == "cell-relax") { - // Ions_Move_Methods IMM.allocate(natom, PARAM.inp.relax_method[0], PARAM.inp.relax_method[1]); - // allocate arrays related to changes of lattice vectors LCM.allocate(); } } -// The interface for relaxation +/** + * @brief Perform one step of relaxation (atomic and/or cell). + * + * Main relaxation loop that coordinates atomic and cell relaxation: + * 1. Check for maximum iteration limit + * 2. Determine calculation mode (relax vs cell-relax) + * 3. Perform atomic relaxation if needed and atoms can move + * 4. If in cell-relax mode and atomic relaxation converged, perform cell relaxation + * + * Convergence behavior: + * - Returns false if relaxation is still in progress + * - Returns true if relaxation has converged or maximum iterations reached + * + * @param istep Current total iteration step + * @param energy Total energy of the system + * @param ucell Unit cell containing atomic positions and lattice vectors + * @param force Ionic forces matrix (natoms x 3) + * @param stress Stress tensor matrix (3 x 3) + * @param force_step Current step counter for force-based relaxation (output) + * @param stress_step Current step counter for stress-based relaxation (output) + * @return true if relaxation is converged, false otherwise + */ bool IonCellOptimizer::relax_step(const int& istep, const double& energy, UnitCell& ucell, @@ -32,29 +59,41 @@ bool IonCellOptimizer::relax_step(const int& istep, { ModuleBase::TITLE("IonCellOptimizer", "relax_step"); + // Reset update flags at the beginning of each step ucell.ionic_position_updated = false; ucell.cell_parameter_updated = false; + // Check if we've reached the maximum number of iterations if (istep == PARAM.inp.relax_nmax) { return true; } + // Determine calculation mode const bool is_cell_relax = (PARAM.inp.calculation == "cell-relax"); const bool is_relax = (PARAM.inp.calculation == "relax"); + // In non-cell-relax mode, force_step follows istep if (!is_cell_relax) { force_step = istep; } + // Determine what relaxation steps are needed const bool need_atom_relax = (is_relax || is_cell_relax) && ucell.if_atoms_can_move(); const bool need_cell_relax = is_cell_relax && ucell.if_cell_can_change(); + // Atomic relaxation branch if (need_atom_relax) { assert(PARAM.inp.cal_force == 1); - bool converged = this->do_relax(istep, force, energy, ucell, force_step, GlobalV::ofs_running); + + // Calculate and apply atomic movement + IMM.cal_movement(istep, force_step, force, energy, ucell, GlobalV::ofs_running); + ++force_step; + + // Check convergence + bool converged = IMM.get_converged(); if (!converged) { ucell.ionic_position_updated = true; @@ -64,15 +103,19 @@ bool IonCellOptimizer::relax_step(const int& istep, { return true; } + // Otherwise, continue to cell relaxation } else if (is_relax) { + // Relax mode but no atoms can move - nothing to do ModuleBase::WARNING("IonCellOptimizer", "No atom is allowed to move!"); return true; } + // Cell relaxation branch (only in cell-relax mode) if (need_cell_relax) { + // Wait for atomic relaxation to converge first (if atoms can move) if (ucell.if_atoms_can_move() && !IMM.get_converged()) { GlobalV::ofs_running << "Note: Need to wait for atomic relaxation first!" << std::endl; @@ -80,45 +123,32 @@ bool IonCellOptimizer::relax_step(const int& istep, } assert(PARAM.inp.cal_stress == 1); - bool converged = this->do_cellrelax(istep, stress_step, stress, energy, ucell, GlobalV::ofs_running); + + // Calculate and apply lattice change + LCM.cal_lattice_change(istep, stress_step, stress, energy, ucell, GlobalV::ofs_running); + bool converged = LCM.get_converged(); + if (!converged) { + // Reset force_step counter after cell change for fresh atomic relaxation force_step = 1; stress_step++; ucell.cell_parameter_updated = true; + + // Update cell-related parameters after volume change unitcell::setup_cell_after_vc(ucell, GlobalV::ofs_running); ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SETUP UNITCELL"); } + return converged; } else if (is_cell_relax) { + // Cell-relax mode but lattice cannot change ModuleBase::WARNING("IonCellOptimizer", "Lattice vectors are not allowed to change!"); return true; } return true; } -bool IonCellOptimizer::do_relax(const int& istep, - const ModuleBase::matrix& ionic_force, - const double& total_energy, - UnitCell& ucell, - int& jstep, - std::ofstream& ofs) -{ - ModuleBase::TITLE("IonCellOptimizer", "do_relax"); - IMM.cal_movement(istep, jstep, ionic_force, total_energy, ucell, ofs); - ++jstep; - return IMM.get_converged(); -} -bool IonCellOptimizer::do_cellrelax(const int& istep, - const int& stress_step, - const ModuleBase::matrix& stress, - const double& total_energy, - UnitCell& ucell, - std::ofstream& ofs) -{ - ModuleBase::TITLE("IonCellOptimizer", "do_cellrelax"); - LCM.cal_lattice_change(istep, stress_step, stress, total_energy, ucell, ofs); - return LCM.get_converged(); -} + diff --git a/source/source_relax/relax_nsync.h b/source/source_relax/relax_nsync.h index 3668519c0a6..5fa76a4c71f 100644 --- a/source/source_relax/relax_nsync.h +++ b/source/source_relax/relax_nsync.h @@ -1,15 +1,48 @@ -#ifndef RELAX_OLD_H -#define RELAX_OLD_H +#ifndef ION_CELL_OPTIMIZER_H +#define ION_CELL_OPTIMIZER_H -#include #include "ions_move_methods.h" #include "lattice_change_methods.h" #include "source_cell/unitcell.h" +/** + * @class IonCellOptimizer + * @brief Optimizer for ionic position relaxation and cell parameter optimization. + * + * This class handles both atomic relaxation and cell relaxation calculations. + * It manages the geometry optimization process by coordinating between + * Ions_Move_Methods (for atomic position updates) and Lattice_Change_Methods + * (for cell parameter updates). + * + * The optimization follows a sequential approach: + * 1. First perform atomic relaxation until convergence + * 2. Then perform cell relaxation (only in cell-relax mode) + */ class IonCellOptimizer { public: + /** + * @brief Initialize relaxation algorithms. + * @param natom Number of atoms in the system + */ void init_relax(const int& natom); + + /** + * @brief Perform one step of relaxation (atomic and/or cell). + * + * This is the main interface for relaxation. Depending on the calculation type + * ("relax" or "cell-relax"), it will perform atomic relaxation, cell relaxation, + * or both in sequence. + * + * @param istep Current total iteration step + * @param energy Total energy of the system + * @param ucell Unit cell containing atomic positions and lattice vectors + * @param force Ionic forces matrix + * @param stress Stress tensor matrix + * @param force_step Current step counter for force-based relaxation + * @param stress_step Current step counter for stress-based relaxation + * @return true if relaxation is converged, false otherwise + */ bool relax_step(const int& istep, const double& energy, UnitCell& ucell, @@ -19,21 +52,8 @@ class IonCellOptimizer int& stress_step); private: - Ions_Move_Methods IMM; - Lattice_Change_Methods LCM; - - bool do_relax(const int& istep, - const ModuleBase::matrix& ionic_force, - const double& total_energy, - UnitCell& ucell, - int& jstep, - std::ofstream& ofs); - bool do_cellrelax(const int& istep, - const int& stress_step, - const ModuleBase::matrix& stress, - const double& total_energy, - UnitCell& ucell, - std::ofstream& ofs); + Ions_Move_Methods IMM; ///< Ionic movement methods for atom relaxation + Lattice_Change_Methods LCM; ///< Lattice change methods for cell relaxation }; #endif \ No newline at end of file From 9968e7e20e0fb3061bc47e265184cd9e90fbbddc Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 11 Jun 2026 16:29:18 +0800 Subject: [PATCH 28/50] optimize --- source/source_relax/relax_nsync.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/source/source_relax/relax_nsync.cpp b/source/source_relax/relax_nsync.cpp index fb3c46d1e82..434e7b4e543 100644 --- a/source/source_relax/relax_nsync.cpp +++ b/source/source_relax/relax_nsync.cpp @@ -97,11 +97,11 @@ bool IonCellOptimizer::relax_step(const int& istep, if (!converged) { ucell.ionic_position_updated = true; - return false; + return false; // not converged } else if (!is_cell_relax) { - return true; + return true; // converged } // Otherwise, continue to cell relaxation } @@ -115,13 +115,6 @@ bool IonCellOptimizer::relax_step(const int& istep, // Cell relaxation branch (only in cell-relax mode) if (need_cell_relax) { - // Wait for atomic relaxation to converge first (if atoms can move) - if (ucell.if_atoms_can_move() && !IMM.get_converged()) - { - GlobalV::ofs_running << "Note: Need to wait for atomic relaxation first!" << std::endl; - return false; - } - assert(PARAM.inp.cal_stress == 1); // Calculate and apply lattice change From ef95a7e2a0e5d606240ab73f458268c239324491 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 11 Jun 2026 16:42:55 +0800 Subject: [PATCH 29/50] update --- source/source_relax/relax_driver.cpp | 36 ++++++++++++++-------------- source/source_relax/relax_driver.h | 1 - source/source_relax/relax_nsync.cpp | 3 +-- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index a5ecdb9aabe..da8278029f0 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -20,15 +20,24 @@ void Relax_Driver::relax_driver( this->init_relax(ucell.nat, inp); this->istep = 1; - bool stop = false; - while (this->istep <= inp.relax_nmax && !stop) + while (this->istep <= inp.relax_nmax) { this->iter_info(inp); this->esolve(p_esolver, ucell); - stop = this->relax_step(p_esolver, ucell, inp); + bool converged = this->relax_step(p_esolver, ucell, inp); this->json_out(p_esolver, ucell, inp); - stop = this->stop_cond(stop); + + // Check stop conditions + if (converged) + { + break; + } + else if (ModuleIO::read_exit_file(GlobalV::MY_RANK, "EXIT", GlobalV::ofs_running)) + { + break; + } + ++this->istep; } @@ -94,24 +103,24 @@ bool Relax_Driver::relax_step(ModuleESolver::ESolver* p_esolver, UnitCell& ucell return false; } - bool stop = false; + bool converged = false; if (inp.relax_new) { - stop = this->rl.relax_step(ucell, this->force_, this->stress_, this->etot); + converged = this->rl.relax_step(ucell, this->force_, this->stress_, this->etot); this->stress_step = this->istep + 1; this->force_step = 1; } else { - stop = this->rl_old.relax_step(this->istep, this->etot, ucell, this->force_, this->stress_, this->force_step, this->stress_step); + converged = this->rl_old.relax_step(this->istep, this->etot, ucell, this->force_, this->stress_, this->force_step, this->stress_step); } this->stru_out(ucell, inp); - ModuleIO::output_after_relax(stop, p_esolver->conv_esolver, GlobalV::ofs_running); + ModuleIO::output_after_relax(converged, p_esolver->conv_esolver, GlobalV::ofs_running); - return stop; + return converged; } void Relax_Driver::stru_out(UnitCell& ucell, const Input_para& inp) @@ -169,15 +178,6 @@ void Relax_Driver::json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, #endif } -bool Relax_Driver::stop_cond(bool stop) -{ - if (stop == false) - { - stop = ModuleIO::read_exit_file(GlobalV::MY_RANK, "EXIT", GlobalV::ofs_running); - } - return stop; -} - void Relax_Driver::final_out(UnitCell& ucell, const Input_para& inp) { if (inp.calculation != "relax" && inp.calculation != "cell-relax") diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index dfc0e1cb333..e06d06fbac4 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -37,7 +37,6 @@ class Relax_Driver bool relax_step(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp); void stru_out(UnitCell& ucell, const Input_para& inp); void json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp); - bool stop_cond(bool stop); void final_out(UnitCell& ucell, const Input_para& inp); }; diff --git a/source/source_relax/relax_nsync.cpp b/source/source_relax/relax_nsync.cpp index 434e7b4e543..4b8a1355004 100644 --- a/source/source_relax/relax_nsync.cpp +++ b/source/source_relax/relax_nsync.cpp @@ -135,9 +135,8 @@ bool IonCellOptimizer::relax_step(const int& istep, return converged; } - else if (is_cell_relax) + else if (is_cell_relax && !ucell.if_cell_can_change()) { - // Cell-relax mode but lattice cannot change ModuleBase::WARNING("IonCellOptimizer", "Lattice vectors are not allowed to change!"); return true; } From 5080b320570c32bc4ddf3bdde505cbdf97d20948 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 11 Jun 2026 16:58:55 +0800 Subject: [PATCH 30/50] improve the logic --- source/source_relax/relax_driver.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index da8278029f0..6f75facb7f8 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -21,6 +21,9 @@ void Relax_Driver::relax_driver( this->istep = 1; + // Main iteration loop for relaxation calculations + // For scf/nscf calculations, relax_step returns true immediately, + // so the loop exits after one iteration while (this->istep <= inp.relax_nmax) { this->iter_info(inp); @@ -31,10 +34,12 @@ void Relax_Driver::relax_driver( // Check stop conditions if (converged) { + // Relaxation converged, exit loop immediately break; } else if (ModuleIO::read_exit_file(GlobalV::MY_RANK, "EXIT", GlobalV::ofs_running)) { + // EXIT file detected, exit loop break; } @@ -98,9 +103,12 @@ void Relax_Driver::esolve(ModuleESolver::ESolver* p_esolver, UnitCell& ucell) bool Relax_Driver::relax_step(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp) { + // Guard: For non-relaxation calculations (scf, nscf, etc.), return true immediately + // to ensure the main loop exits after one iteration. This provides robustness + // even if relax_nmax is set to a large value. if (inp.calculation != "relax" && inp.calculation != "cell-relax") { - return false; + return true; } bool converged = false; @@ -113,7 +121,8 @@ bool Relax_Driver::relax_step(ModuleESolver::ESolver* p_esolver, UnitCell& ucell } else { - converged = this->rl_old.relax_step(this->istep, this->etot, ucell, this->force_, this->stress_, this->force_step, this->stress_step); + converged = this->rl_old.relax_step(this->istep, this->etot, ucell, this->force_, + this->stress_, this->force_step, this->stress_step); } this->stru_out(ucell, inp); @@ -210,4 +219,4 @@ void Relax_Driver::final_out(UnitCell& ucell, const Input_para& inp) std::cout << " relax_nmax = 0, DRY RUN TEST SUCCEEDS :)" << std::endl; std::cout << "-----------------------------------------------" << std::endl; } -} \ No newline at end of file +} From d56ba5044ce3b23838939e87633e3944b70a20e3 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 11 Jun 2026 17:08:03 +0800 Subject: [PATCH 31/50] update --- source/source_relax/relax_driver.cpp | 41 ++++++++++++++-------------- source/source_relax/relax_driver.h | 11 ++++---- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index 6f75facb7f8..ac6130a0d5e 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -1,5 +1,4 @@ #include "relax_driver.h" - #include "source_base/global_file.h" #include "source_io/module_output/cif_io.h" #include "source_io/module_json/output_info.h" @@ -19,16 +18,16 @@ void Relax_Driver::relax_driver( this->init_relax(ucell.nat, inp); - this->istep = 1; + int istep = 1; // Main iteration loop for relaxation calculations // For scf/nscf calculations, relax_step returns true immediately, // so the loop exits after one iteration - while (this->istep <= inp.relax_nmax) + while (istep <= inp.relax_nmax) { - this->iter_info(inp); - this->esolve(p_esolver, ucell); - bool converged = this->relax_step(p_esolver, ucell, inp); + this->iter_info(istep, inp); + this->esolve(istep, p_esolver, ucell); + bool converged = this->relax_step(istep, p_esolver, ucell, inp); this->json_out(p_esolver, ucell, inp); // Check stop conditions @@ -43,10 +42,10 @@ void Relax_Driver::relax_driver( break; } - ++this->istep; + ++istep; } - this->final_out(ucell, inp); + this->final_out(istep, ucell, inp); ModuleBase::timer::end("Relax_Driver", "relax_driver"); return; @@ -67,7 +66,7 @@ void Relax_Driver::init_relax(const int nat, const Input_para& inp) } } -void Relax_Driver::iter_info(const Input_para& inp) +void Relax_Driver::iter_info(const int istep, const Input_para& inp) { if (inp.out_level == "ie" && (inp.calculation == "relax" @@ -76,7 +75,7 @@ void Relax_Driver::iter_info(const Input_para& inp) || inp.calculation == "nscf") && (inp.esolver_type != "lr")) { - ModuleIO::print_screen(this->stress_step, this->force_step, this->istep); + ModuleIO::print_screen(this->stress_step, this->force_step, istep); } #ifdef __RAPIDJSON @@ -84,9 +83,9 @@ void Relax_Driver::iter_info(const Input_para& inp) #endif } -void Relax_Driver::esolve(ModuleESolver::ESolver* p_esolver, UnitCell& ucell) +void Relax_Driver::esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell) { - p_esolver->runner(ucell, this->istep - 1); + p_esolver->runner(ucell, istep - 1); this->etot = p_esolver->cal_energy(); @@ -101,7 +100,7 @@ void Relax_Driver::esolve(ModuleESolver::ESolver* p_esolver, UnitCell& ucell) } } -bool Relax_Driver::relax_step(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp) +bool Relax_Driver::relax_step(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp) { // Guard: For non-relaxation calculations (scf, nscf, etc.), return true immediately // to ensure the main loop exits after one iteration. This provides robustness @@ -116,23 +115,23 @@ bool Relax_Driver::relax_step(ModuleESolver::ESolver* p_esolver, UnitCell& ucell if (inp.relax_new) { converged = this->rl.relax_step(ucell, this->force_, this->stress_, this->etot); - this->stress_step = this->istep + 1; + this->stress_step = istep + 1; this->force_step = 1; } else { - converged = this->rl_old.relax_step(this->istep, this->etot, ucell, this->force_, + converged = this->rl_old.relax_step(istep, this->etot, ucell, this->force_, this->stress_, this->force_step, this->stress_step); } - this->stru_out(ucell, inp); + this->stru_out(istep, ucell, inp); ModuleIO::output_after_relax(converged, p_esolver->conv_esolver, GlobalV::ofs_running); return converged; } -void Relax_Driver::stru_out(UnitCell& ucell, const Input_para& inp) +void Relax_Driver::stru_out(const int istep, UnitCell& ucell, const Input_para& inp) { bool need_orb = inp.basis_type == "pw"; need_orb = need_orb && inp.init_wfc.substr(0, 3) == "nao"; @@ -157,7 +156,7 @@ void Relax_Driver::stru_out(UnitCell& ucell, const Input_para& inp) if (Ions_Move_Basic::out_stru) { ss1 << PARAM.globalv.global_out_dir << "STRU_ION"; - ss1 << this->istep << "_D"; + ss1 << istep << "_D"; unitcell::print_stru_file(ucell, ucell.atoms, ucell.latvec, @@ -187,7 +186,7 @@ void Relax_Driver::json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, #endif } -void Relax_Driver::final_out(UnitCell& ucell, const Input_para& inp) +void Relax_Driver::final_out(const int istep, UnitCell& ucell, const Input_para& inp) { if (inp.calculation != "relax" && inp.calculation != "cell-relax") { @@ -199,7 +198,7 @@ void Relax_Driver::final_out(UnitCell& ucell, const Input_para& inp) "# Generated by ABACUS ModuleIO::CifParser", "data_?"); - if (this->istep - 1 == inp.relax_nmax) + if (istep - 1 == inp.relax_nmax) { std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; std::cout << " Geometry relaxation stops here due to reaching the maximum " << std::endl; @@ -209,7 +208,7 @@ void Relax_Driver::final_out(UnitCell& ucell, const Input_para& inp) else { std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; - std::cout << " Geometry relaxation thresholds are reached within " << this->istep - 1 << " steps." << std::endl; + std::cout << " Geometry relaxation thresholds are reached within " << istep - 1 << " steps." << std::endl; std::cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; } diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index e06d06fbac4..d26636a4362 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -20,7 +20,6 @@ class Relax_Driver const Input_para& inp); private: - int istep = 0; double etot = 0; int force_step = 1; int stress_step = 1; @@ -32,12 +31,12 @@ class Relax_Driver IonCellOptimizer rl_old; void init_relax(const int nat, const Input_para& inp); - void iter_info(const Input_para& inp); - void esolve(ModuleESolver::ESolver* p_esolver, UnitCell& ucell); - bool relax_step(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp); - void stru_out(UnitCell& ucell, const Input_para& inp); + void iter_info(const int istep, const Input_para& inp); + void esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell); + bool relax_step(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp); + void stru_out(const int istep, UnitCell& ucell, const Input_para& inp); void json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp); - void final_out(UnitCell& ucell, const Input_para& inp); + void final_out(const int istep, UnitCell& ucell, const Input_para& inp); }; #endif From 8f2915f697eb00198f3964be9e8af2858d252340 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 11 Jun 2026 17:09:00 +0800 Subject: [PATCH 32/50] change istep starting from 0 --- source/source_relax/relax_driver.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index ac6130a0d5e..209a214391c 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -18,16 +18,16 @@ void Relax_Driver::relax_driver( this->init_relax(ucell.nat, inp); - int istep = 1; + int istep = 0; // Main iteration loop for relaxation calculations // For scf/nscf calculations, relax_step returns true immediately, // so the loop exits after one iteration - while (istep <= inp.relax_nmax) + while (istep < inp.relax_nmax) { - this->iter_info(istep, inp); - this->esolve(istep, p_esolver, ucell); - bool converged = this->relax_step(istep, p_esolver, ucell, inp); + this->iter_info(istep-1, inp); + this->esolve(istep-1, p_esolver, ucell); + bool converged = this->relax_step(istep-1, p_esolver, ucell, inp); this->json_out(p_esolver, ucell, inp); // Check stop conditions From e33c561f27e7346f1a705271cb83e06fd4d7709d Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Thu, 11 Jun 2026 17:23:28 +0800 Subject: [PATCH 33/50] update istep, should be starting from 0, when output, should be istep+1 --- source/source_relax/relax_driver.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index 209a214391c..74ce99f2790 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -25,9 +25,9 @@ void Relax_Driver::relax_driver( // so the loop exits after one iteration while (istep < inp.relax_nmax) { - this->iter_info(istep-1, inp); - this->esolve(istep-1, p_esolver, ucell); - bool converged = this->relax_step(istep-1, p_esolver, ucell, inp); + this->iter_info(istep, inp); + this->esolve(istep, p_esolver, ucell); + bool converged = this->relax_step(istep, p_esolver, ucell, inp); this->json_out(p_esolver, ucell, inp); // Check stop conditions @@ -45,7 +45,7 @@ void Relax_Driver::relax_driver( ++istep; } - this->final_out(istep, ucell, inp); + this->final_out(istep+1, ucell, inp); ModuleBase::timer::end("Relax_Driver", "relax_driver"); return; @@ -75,7 +75,7 @@ void Relax_Driver::iter_info(const int istep, const Input_para& inp) || inp.calculation == "nscf") && (inp.esolver_type != "lr")) { - ModuleIO::print_screen(this->stress_step, this->force_step, istep); + ModuleIO::print_screen(this->stress_step, this->force_step, istep+1); } #ifdef __RAPIDJSON @@ -85,7 +85,7 @@ void Relax_Driver::iter_info(const int istep, const Input_para& inp) void Relax_Driver::esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell) { - p_esolver->runner(ucell, istep - 1); + p_esolver->runner(ucell, istep); this->etot = p_esolver->cal_energy(); @@ -115,16 +115,16 @@ bool Relax_Driver::relax_step(const int istep, ModuleESolver::ESolver* p_esolver if (inp.relax_new) { converged = this->rl.relax_step(ucell, this->force_, this->stress_, this->etot); - this->stress_step = istep + 1; + this->stress_step++; this->force_step = 1; } else { - converged = this->rl_old.relax_step(istep, this->etot, ucell, this->force_, + converged = this->rl_old.relax_step(istep+1, this->etot, ucell, this->force_, this->stress_, this->force_step, this->stress_step); } - this->stru_out(istep, ucell, inp); + this->stru_out(istep+1, ucell, inp); ModuleIO::output_after_relax(converged, p_esolver->conv_esolver, GlobalV::ofs_running); From 74da953a2657ea43d095f0ef905b42f8089cfe70 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Fri, 12 Jun 2026 08:26:09 +0800 Subject: [PATCH 34/50] remove class variables --- source/source_relax/relax_driver.cpp | 27 +++++++++++++++------------ source/source_relax/relax_driver.h | 9 +++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index 74ce99f2790..677fe8588b8 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -25,10 +25,13 @@ void Relax_Driver::relax_driver( // so the loop exits after one iteration while (istep < inp.relax_nmax) { + ModuleBase::matrix force(ucell.nat, 3); + ModuleBase::matrix stress(3, 3); + this->iter_info(istep, inp); - this->esolve(istep, p_esolver, ucell); - bool converged = this->relax_step(istep, p_esolver, ucell, inp); - this->json_out(p_esolver, ucell, inp); + this->esolve(istep, p_esolver, ucell, force, stress); + bool converged = this->relax_step(istep, p_esolver, ucell, inp, force, stress); + this->json_out(p_esolver, ucell, inp, force, stress); // Check stop conditions if (converged) @@ -83,7 +86,7 @@ void Relax_Driver::iter_info(const int istep, const Input_para& inp) #endif } -void Relax_Driver::esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell) +void Relax_Driver::esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, ModuleBase::matrix& force, ModuleBase::matrix& stress) { p_esolver->runner(ucell, istep); @@ -91,16 +94,16 @@ void Relax_Driver::esolve(const int istep, ModuleESolver::ESolver* p_esolver, Un if (PARAM.inp.cal_force) { - p_esolver->cal_force(ucell, this->force_); + p_esolver->cal_force(ucell, force); } if (PARAM.inp.cal_stress) { - p_esolver->cal_stress(ucell, this->stress_); + p_esolver->cal_stress(ucell, stress); } } -bool Relax_Driver::relax_step(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp) +bool Relax_Driver::relax_step(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress) { // Guard: For non-relaxation calculations (scf, nscf, etc.), return true immediately // to ensure the main loop exits after one iteration. This provides robustness @@ -114,14 +117,14 @@ bool Relax_Driver::relax_step(const int istep, ModuleESolver::ESolver* p_esolver if (inp.relax_new) { - converged = this->rl.relax_step(ucell, this->force_, this->stress_, this->etot); + converged = this->rl.relax_step(ucell, force, stress, this->etot); this->stress_step++; this->force_step = 1; } else { - converged = this->rl_old.relax_step(istep+1, this->etot, ucell, this->force_, - this->stress_, this->force_step, this->stress_step); + converged = this->rl_old.relax_step(istep+1, this->etot, ucell, force, + stress, this->force_step, this->stress_step); } this->stru_out(istep+1, ucell, inp); @@ -175,14 +178,14 @@ void Relax_Driver::stru_out(const int istep, UnitCell& ucell, const Input_para& } } -void Relax_Driver::json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp) +void Relax_Driver::json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress) { #ifdef __RAPIDJSON Json::add_output_energy(p_esolver->cal_energy() * ModuleBase::Ry_to_eV); double unit_transform = ModuleBase::RYDBERG_SI / pow(ModuleBase::BOHR_RADIUS_SI, 3) * 1.0e-8; double fac = ModuleBase::Ry_to_eV / 0.529177; - Json::add_output_cell_coo_stress_force(&ucell, this->force_, fac, this->stress_, unit_transform); + Json::add_output_cell_coo_stress_force(&ucell, force, fac, stress, unit_transform); #endif } diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index d26636a4362..43afbb6cb5f 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -24,18 +24,15 @@ class Relax_Driver int force_step = 1; int stress_step = 1; - ModuleBase::matrix force_; - ModuleBase::matrix stress_; - Relax rl; IonCellOptimizer rl_old; void init_relax(const int nat, const Input_para& inp); void iter_info(const int istep, const Input_para& inp); - void esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell); - bool relax_step(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp); + void esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, ModuleBase::matrix& force, ModuleBase::matrix& stress); + bool relax_step(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress); void stru_out(const int istep, UnitCell& ucell, const Input_para& inp); - void json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp); + void json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress); void final_out(const int istep, UnitCell& ucell, const Input_para& inp); }; From 9433e405e37065c05fa5893ae9929c3567384616 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Fri, 12 Jun 2026 08:30:46 +0800 Subject: [PATCH 35/50] update --- source/source_relax/relax_driver.cpp | 26 +++++++++++++++++++------- source/source_relax/relax_driver.h | 5 ++--- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index 677fe8588b8..09b6559916e 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -27,10 +27,11 @@ void Relax_Driver::relax_driver( { ModuleBase::matrix force(ucell.nat, 3); ModuleBase::matrix stress(3, 3); + double etot = 0.0; this->iter_info(istep, inp); - this->esolve(istep, p_esolver, ucell, force, stress); - bool converged = this->relax_step(istep, p_esolver, ucell, inp, force, stress); + this->esolve(istep, p_esolver, ucell, force, stress, etot); + bool converged = this->relax_step(istep, p_esolver, ucell, inp, force, stress, etot); this->json_out(p_esolver, ucell, inp, force, stress); // Check stop conditions @@ -86,11 +87,16 @@ void Relax_Driver::iter_info(const int istep, const Input_para& inp) #endif } -void Relax_Driver::esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, ModuleBase::matrix& force, ModuleBase::matrix& stress) +void Relax_Driver::esolve(const int istep, + ModuleESolver::ESolver* p_esolver, + UnitCell& ucell, + ModuleBase::matrix& force, + ModuleBase::matrix& stress, + double& etot) { p_esolver->runner(ucell, istep); - this->etot = p_esolver->cal_energy(); + etot = p_esolver->cal_energy(); if (PARAM.inp.cal_force) { @@ -103,7 +109,13 @@ void Relax_Driver::esolve(const int istep, ModuleESolver::ESolver* p_esolver, Un } } -bool Relax_Driver::relax_step(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress) +bool Relax_Driver::relax_step(const int istep, + ModuleESolver::ESolver* p_esolver, + UnitCell& ucell, + const Input_para& inp, + const ModuleBase::matrix& force, + const ModuleBase::matrix& stress, + const double etot) { // Guard: For non-relaxation calculations (scf, nscf, etc.), return true immediately // to ensure the main loop exits after one iteration. This provides robustness @@ -117,13 +129,13 @@ bool Relax_Driver::relax_step(const int istep, ModuleESolver::ESolver* p_esolver if (inp.relax_new) { - converged = this->rl.relax_step(ucell, force, stress, this->etot); + converged = this->rl.relax_step(ucell, force, stress, etot); this->stress_step++; this->force_step = 1; } else { - converged = this->rl_old.relax_step(istep+1, this->etot, ucell, force, + converged = this->rl_old.relax_step(istep+1, etot, ucell, force, stress, this->force_step, this->stress_step); } diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index 43afbb6cb5f..1c7a457374e 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -20,7 +20,6 @@ class Relax_Driver const Input_para& inp); private: - double etot = 0; int force_step = 1; int stress_step = 1; @@ -29,8 +28,8 @@ class Relax_Driver void init_relax(const int nat, const Input_para& inp); void iter_info(const int istep, const Input_para& inp); - void esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, ModuleBase::matrix& force, ModuleBase::matrix& stress); - bool relax_step(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress); + void esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, ModuleBase::matrix& force, ModuleBase::matrix& stress, double& etot); + bool relax_step(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress, const double etot); void stru_out(const int istep, UnitCell& ucell, const Input_para& inp); void json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress); void final_out(const int istep, UnitCell& ucell, const Input_para& inp); From ea84dbb001a499730f6220c16584e10dfb82f325 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Fri, 12 Jun 2026 08:39:51 +0800 Subject: [PATCH 36/50] update --- source/source_relax/relax_driver.cpp | 54 +++++++------- source/source_relax/relax_driver.h | 102 ++++++++++++++++++++++++--- 2 files changed, 123 insertions(+), 33 deletions(-) diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index 09b6559916e..9a92d843e10 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -9,29 +9,32 @@ #include "source_cell/print_cell.h" void Relax_Driver::relax_driver( - ModuleESolver::ESolver* p_esolver, + ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp) -{ +{ ModuleBase::TITLE("Relax_Driver", "relax_driver"); ModuleBase::timer::start("Relax_Driver", "relax_driver"); this->init_relax(ucell.nat, inp); - int istep = 0; + // steps[0]: istep (main iteration step) + // steps[1]: force_step + // steps[2]: stress_step + std::vector steps = {0, 1, 1}; // Main iteration loop for relaxation calculations // For scf/nscf calculations, relax_step returns true immediately, // so the loop exits after one iteration - while (istep < inp.relax_nmax) + while (steps[0] < inp.relax_nmax) { ModuleBase::matrix force(ucell.nat, 3); ModuleBase::matrix stress(3, 3); double etot = 0.0; - this->iter_info(istep, inp); - this->esolve(istep, p_esolver, ucell, force, stress, etot); - bool converged = this->relax_step(istep, p_esolver, ucell, inp, force, stress, etot); + this->iter_info(steps, inp); + this->esolve(steps[0], p_esolver, ucell, force, stress, etot); + bool converged = this->relax_step(steps, p_esolver, ucell, inp, force, stress, etot); this->json_out(p_esolver, ucell, inp, force, stress); // Check stop conditions @@ -46,10 +49,10 @@ void Relax_Driver::relax_driver( break; } - ++istep; + ++steps[0]; } - this->final_out(istep+1, ucell, inp); + this->final_out(steps[0]+1, ucell, inp); ModuleBase::timer::end("Relax_Driver", "relax_driver"); return; @@ -70,16 +73,16 @@ void Relax_Driver::init_relax(const int nat, const Input_para& inp) } } -void Relax_Driver::iter_info(const int istep, const Input_para& inp) +void Relax_Driver::iter_info(const std::vector& steps, const Input_para& inp) { if (inp.out_level == "ie" - && (inp.calculation == "relax" - || inp.calculation == "cell-relax" + && (inp.calculation == "relax" + || inp.calculation == "cell-relax" || inp.calculation == "scf" || inp.calculation == "nscf") && (inp.esolver_type != "lr")) { - ModuleIO::print_screen(this->stress_step, this->force_step, istep+1); + ModuleIO::print_screen(steps[2], steps[1], steps[0]+1); } #ifdef __RAPIDJSON @@ -109,12 +112,12 @@ void Relax_Driver::esolve(const int istep, } } -bool Relax_Driver::relax_step(const int istep, - ModuleESolver::ESolver* p_esolver, - UnitCell& ucell, - const Input_para& inp, - const ModuleBase::matrix& force, - const ModuleBase::matrix& stress, +bool Relax_Driver::relax_step(std::vector& steps, + ModuleESolver::ESolver* p_esolver, + UnitCell& ucell, + const Input_para& inp, + const ModuleBase::matrix& force, + const ModuleBase::matrix& stress, const double etot) { // Guard: For non-relaxation calculations (scf, nscf, etc.), return true immediately @@ -130,16 +133,18 @@ bool Relax_Driver::relax_step(const int istep, if (inp.relax_new) { converged = this->rl.relax_step(ucell, force, stress, etot); - this->stress_step++; - this->force_step = 1; + // stress step +1 + steps[2]++; + // fix force step to 1 + steps[1] = 1; } else { - converged = this->rl_old.relax_step(istep+1, etot, ucell, force, - stress, this->force_step, this->stress_step); + converged = this->rl_old.relax_step(steps[0]+1, etot, ucell, force, + stress, steps[1], steps[2]); } - this->stru_out(istep+1, ucell, inp); + this->stru_out(steps[0]+1, ucell, inp); ModuleIO::output_after_relax(converged, p_esolver->conv_esolver, GlobalV::ofs_running); @@ -183,6 +188,7 @@ void Relax_Driver::stru_out(const int istep, UnitCell& ucell, const Input_para& need_orb, PARAM.globalv.deepks_setorb, GlobalV::MY_RANK); + ModuleIO::CifParser::write(PARAM.globalv.global_out_dir + "STRU_NOW.cif", ucell, "# Generated by ABACUS ModuleIO::CifParser", diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index 1c7a457374e..96fd1e7064a 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -7,7 +7,14 @@ #include "relax_nsync.h" #include "source_io/module_parameter/input_parameter.h" #include "source_base/matrix.h" +#include +/** + * @brief Driver class for geometry relaxation calculations. + * + * This class manages the main relaxation loop, including energy solving, + * force/stress calculation, and structure optimization steps. + */ class Relax_Driver { @@ -15,23 +22,100 @@ class Relax_Driver Relax_Driver(){}; ~Relax_Driver(){}; - void relax_driver(ModuleESolver::ESolver* p_esolver, - UnitCell& ucell, + /** + * @brief Main driver function for relaxation calculations. + * + * This function executes the main iteration loop for relaxation, + * calling energy solver and structure optimization steps until + * convergence or maximum steps reached. + * + * @param p_esolver Pointer to the energy solver. + * @param ucell Reference to the unit cell to be relaxed. + * @param inp Input parameters for the calculation. + */ + void relax_driver(ModuleESolver::ESolver* p_esolver, + UnitCell& ucell, const Input_para& inp); private: - int force_step = 1; - int stress_step = 1; - + /// New relaxation optimizer (Relax class) Relax rl; + /// Old relaxation optimizer (IonCellOptimizer class) IonCellOptimizer rl_old; + /** + * @brief Initialize the relaxation optimizer. + * + * @param nat Number of atoms in the unit cell. + * @param inp Input parameters for the calculation. + */ void init_relax(const int nat, const Input_para& inp); - void iter_info(const int istep, const Input_para& inp); - void esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, ModuleBase::matrix& force, ModuleBase::matrix& stress, double& etot); - bool relax_step(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress, const double etot); + + /** + * @brief Print iteration information to screen. + * + * @param steps Vector containing step counters: steps[0]=istep, steps[1]=force_step, steps[2]=stress_step. + * @param inp Input parameters for the calculation. + */ + void iter_info(const std::vector& steps, const Input_para& inp); + + /** + * @brief Perform energy solving for the current step. + * + * @param istep Current iteration step. + * @param p_esolver Pointer to the energy solver. + * @param ucell Reference to the unit cell. + * @param force Output matrix for calculated forces. + * @param stress Output matrix for calculated stress. + * @param etot Output total energy. + */ + void esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, + ModuleBase::matrix& force, ModuleBase::matrix& stress, double& etot); + + /** + * @brief Perform one relaxation step. + * + * @param steps Vector containing step counters (modified in place): steps[0]=istep, steps[1]=force_step, steps[2]=stress_step. + * @param p_esolver Pointer to the energy solver. + * @param ucell Reference to the unit cell. + * @param inp Input parameters for the calculation. + * @param force Matrix of calculated forces. + * @param stress Matrix of calculated stress. + * @param etot Total energy. + * @return True if relaxation converged, false otherwise. + */ + bool relax_step(std::vector& steps, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, + const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress, + const double etot); + + /** + * @brief Output structure files after relaxation step. + * + * @param istep Current iteration step. + * @param ucell Reference to the unit cell. + * @param inp Input parameters for the calculation. + */ void stru_out(const int istep, UnitCell& ucell, const Input_para& inp); - void json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress); + + /** + * @brief Output JSON format results. + * + * @param p_esolver Pointer to the energy solver. + * @param ucell Reference to the unit cell. + * @param inp Input parameters for the calculation. + * @param force Matrix of calculated forces. + * @param stress Matrix of calculated stress. + */ + void json_out(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, + const ModuleBase::matrix& force, const ModuleBase::matrix& stress); + + /** + * @brief Output final results after relaxation. + * + * @param istep Final iteration step. + * @param ucell Reference to the unit cell. + * @param inp Input parameters for the calculation. + */ void final_out(const int istep, UnitCell& ucell, const Input_para& inp); }; From 07612882735f31796c51594d965cf711f04b1f95 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Fri, 12 Jun 2026 08:45:43 +0800 Subject: [PATCH 37/50] update --- source/source_relax/relax_driver.cpp | 17 +++++++++-------- source/source_relax/relax_driver.h | 3 ++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index 9a92d843e10..429e8687844 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -33,7 +33,7 @@ void Relax_Driver::relax_driver( double etot = 0.0; this->iter_info(steps, inp); - this->esolve(steps[0], p_esolver, ucell, force, stress, etot); + this->esolve(steps[0], p_esolver, ucell, inp, force, stress, etot); bool converged = this->relax_step(steps, p_esolver, ucell, inp, force, stress, etot); this->json_out(p_esolver, ucell, inp, force, stress); @@ -90,23 +90,24 @@ void Relax_Driver::iter_info(const std::vector& steps, const Input_para& in #endif } -void Relax_Driver::esolve(const int istep, - ModuleESolver::ESolver* p_esolver, - UnitCell& ucell, - ModuleBase::matrix& force, - ModuleBase::matrix& stress, +void Relax_Driver::esolve(const int istep, + ModuleESolver::ESolver* p_esolver, + UnitCell& ucell, + const Input_para& inp, + ModuleBase::matrix& force, + ModuleBase::matrix& stress, double& etot) { p_esolver->runner(ucell, istep); etot = p_esolver->cal_energy(); - if (PARAM.inp.cal_force) + if (inp.cal_force) { p_esolver->cal_force(ucell, force); } - if (PARAM.inp.cal_stress) + if (inp.cal_stress) { p_esolver->cal_stress(ucell, stress); } diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index 96fd1e7064a..9e045dd2fe8 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -65,12 +65,13 @@ class Relax_Driver * @param istep Current iteration step. * @param p_esolver Pointer to the energy solver. * @param ucell Reference to the unit cell. + * @param inp Input parameters for the calculation. * @param force Output matrix for calculated forces. * @param stress Output matrix for calculated stress. * @param etot Output total energy. */ void esolve(const int istep, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, - ModuleBase::matrix& force, ModuleBase::matrix& stress, double& etot); + const Input_para& inp, ModuleBase::matrix& force, ModuleBase::matrix& stress, double& etot); /** * @brief Perform one relaxation step. From 4538341025f4269e71fbf73c2e2e062c57f8858d Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Fri, 12 Jun 2026 09:25:34 +0800 Subject: [PATCH 38/50] update --- .../pyabacus/src/ModuleDriver/py_driver.cpp | 2 +- source/source_main/driver_run.cpp | 2 +- source/source_relax/ions_move_bfgs.cpp | 4 +- source/source_relax/ions_move_bfgs2.cpp | 4 +- source/source_relax/ions_move_bfgs2.h | 3 +- source/source_relax/ions_move_lbfgs.cpp | 5 +-- source/source_relax/ions_move_lbfgs.h | 6 ++- source/source_relax/ions_move_methods.cpp | 4 +- source/source_relax/line_search.cpp | 11 +++--- source/source_relax/line_search.h | 7 +++- source/source_relax/relax_driver.cpp | 16 ++++---- source/source_relax/relax_driver.h | 8 +++- source/source_relax/relax_nsync.cpp | 11 +++--- source/source_relax/relax_nsync.h | 9 +++-- source/source_relax/relax_sync.cpp | 39 ++++++++++--------- source/source_relax/relax_sync.h | 12 +++--- source/source_relax/test/bfgs_test.cpp | 10 ++++- .../test/ions_move_methods_test.cpp | 12 +++--- source/source_relax/test/line_search_test.cpp | 31 ++++++++------- source/source_relax/test/relax_test.cpp | 12 +++--- 20 files changed, 120 insertions(+), 88 deletions(-) diff --git a/python/pyabacus/src/ModuleDriver/py_driver.cpp b/python/pyabacus/src/ModuleDriver/py_driver.cpp index 7f5279e8e78..1c908c3968b 100644 --- a/python/pyabacus/src/ModuleDriver/py_driver.cpp +++ b/python/pyabacus/src/ModuleDriver/py_driver.cpp @@ -442,7 +442,7 @@ CalculationResult PyDriver::run( if (cal == "scf" || cal == "relax" || cal == "cell-relax" || cal == "nscf") { Relax_Driver rl_driver; - rl_driver.relax_driver(impl_->p_esolver_, *impl_->ucell_, PARAM.inp); + rl_driver.relax_driver(impl_->p_esolver_, *impl_->ucell_, PARAM.inp, GlobalV::ofs_running); } else if (cal == "get_s") { diff --git a/source/source_main/driver_run.cpp b/source/source_main/driver_run.cpp index ab899ad7a60..4911b133de0 100644 --- a/source/source_main/driver_run.cpp +++ b/source/source_main/driver_run.cpp @@ -81,7 +81,7 @@ void Driver::driver_run() else if (cal == "scf" || cal == "relax" || cal == "cell-relax" || cal == "nscf") { Relax_Driver rl_driver; - rl_driver.relax_driver(p_esolver, ucell, PARAM.inp); + rl_driver.relax_driver(p_esolver, ucell, PARAM.inp, GlobalV::ofs_running); } else if (cal == "get_s") { diff --git a/source/source_relax/ions_move_bfgs.cpp b/source/source_relax/ions_move_bfgs.cpp index 3330e874aac..c8df2904050 100644 --- a/source/source_relax/ions_move_bfgs.cpp +++ b/source/source_relax/ions_move_bfgs.cpp @@ -301,8 +301,8 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0, std::ofstream& ofs) std::cout << " BFGS TRUST (Bohr) : " << trust_radius << std::endl; } - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "istep", Ions_Move_Basic::istep); - ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "update iteration", Ions_Move_Basic::update_iter); + ModuleBase::GlobalFunc::OUT(ofs, "istep", Ions_Move_Basic::istep); + ModuleBase::GlobalFunc::OUT(ofs, "update iteration", Ions_Move_Basic::update_iter); // combine the direction and move length now double norm = dot_func(this->move.data(), this->move.data(), dim); diff --git a/source/source_relax/ions_move_bfgs2.cpp b/source/source_relax/ions_move_bfgs2.cpp index 79fedd84db9..bbd3167e416 100644 --- a/source/source_relax/ions_move_bfgs2.cpp +++ b/source/source_relax/ions_move_bfgs2.cpp @@ -34,7 +34,7 @@ void Ions_Move_BFGS2::allocate(const int _size) } -void Ions_Move_BFGS2::relax_step(const ModuleBase::matrix& _force,UnitCell& ucell) +void Ions_Move_BFGS2::relax_step(const ModuleBase::matrix& _force,UnitCell& ucell, std::ofstream& ofs_running) { if(!is_initialized) { @@ -81,7 +81,7 @@ void Ions_Move_BFGS2::relax_step(const ModuleBase::matrix& _force,UnitCell& ucel this->CalculateLargestGrad(_force,ucell); this->IsRestrain(); // print out geometry information during bfgs_trad relax - unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,GlobalV::ofs_running); + unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,ofs_running); } void Ions_Move_BFGS2::GetPos(UnitCell& ucell,std::vector>& pos) diff --git a/source/source_relax/ions_move_bfgs2.h b/source/source_relax/ions_move_bfgs2.h index aa8f4ca2055..baa9f44056a 100644 --- a/source/source_relax/ions_move_bfgs2.h +++ b/source/source_relax/ions_move_bfgs2.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "source_base/matrix.h" #include "source_base/matrix3.h" #include "source_cell/unitcell.h" @@ -14,7 +15,7 @@ class Ions_Move_BFGS2 { public: void allocate(const int _size);//initialize parameters - void relax_step(const ModuleBase::matrix& _force,UnitCell& ucell);//a full iteration step + void relax_step(const ModuleBase::matrix& _force,UnitCell& ucell, std::ofstream& ofs_running);//a full iteration step private: diff --git a/source/source_relax/ions_move_lbfgs.cpp b/source/source_relax/ions_move_lbfgs.cpp index ae528f1eedd..39c554d7e90 100644 --- a/source/source_relax/ions_move_lbfgs.cpp +++ b/source/source_relax/ions_move_lbfgs.cpp @@ -25,8 +25,7 @@ void Ions_Move_LBFGS::allocate(const int _size) // initialize H0、H、pos0、fo //l_search.init_line_search(); } -void Ions_Move_LBFGS::relax_step(const ModuleBase::matrix _force,UnitCell& ucell,const double &etot) - +void Ions_Move_LBFGS::relax_step(const ModuleBase::matrix _force,UnitCell& ucell,const double &etot, std::ofstream& ofs_running) { get_pos(ucell,pos); get_pos_taud(ucell,pos_taud); @@ -65,7 +64,7 @@ void Ions_Move_LBFGS::relax_step(const ModuleBase::matrix _force,UnitCell& ucell this->calculate_largest_grad(_force,ucell); this->is_restrain(); // mohan add 2025-06-22 - unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,GlobalV::ofs_running); + unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,ofs_running); } void Ions_Move_LBFGS::get_pos(UnitCell& ucell,std::vector>& pos) diff --git a/source/source_relax/ions_move_lbfgs.h b/source/source_relax/ions_move_lbfgs.h index c081a8e9a34..62f2cfd7221 100644 --- a/source/source_relax/ions_move_lbfgs.h +++ b/source/source_relax/ions_move_lbfgs.h @@ -5,6 +5,7 @@ #include #include #include +#include //#include "line_search.h" #include "source_base/matrix.h" #include "source_base/matrix3.h" @@ -30,11 +31,12 @@ class Ions_Move_LBFGS * @param _force Current force * @param ucell Unit cell to optimize * @param etot Current total energy - * @param p_esolver Structure solver + * @param ofs_running Output stream for running log */ void relax_step(const ModuleBase::matrix _force, UnitCell& ucell, - const double &etot); + const double &etot, + std::ofstream& ofs_running); private: //LineSearch l_search; diff --git a/source/source_relax/ions_move_methods.cpp b/source/source_relax/ions_move_methods.cpp index 0547472f2d6..b22f15d7b24 100644 --- a/source/source_relax/ions_move_methods.cpp +++ b/source/source_relax/ions_move_methods.cpp @@ -84,11 +84,11 @@ void Ions_Move_Methods::cal_movement(const int &istep, } else if(Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] == "1") { - bfgs_trad.relax_step(f,ucell); + bfgs_trad.relax_step(f,ucell, ofs); } else if(Ions_Move_Basic::relax_method[0] == "lbfgs") { - lbfgs.relax_step(f,ucell,etot); + lbfgs.relax_step(f,ucell,etot, ofs); } else { diff --git a/source/source_relax/line_search.cpp b/source/source_relax/line_search.cpp index 70ccc54956c..b557e9d60ba 100644 --- a/source/source_relax/line_search.cpp +++ b/source/source_relax/line_search.cpp @@ -11,7 +11,8 @@ bool Line_Search::line_search(const bool restart, const double y, // function value at current point const double f, // derivative at current point double& xnew, // the next point that we want to try - const double conv_thr) + const double conv_thr, + std::ofstream& ofs_running) { if (restart) { @@ -39,7 +40,7 @@ bool Line_Search::line_search(const bool restart, if (ls_step >= 2) { - return this->brent(x, y, f, xnew, conv_thr); + return this->brent(x, y, f, xnew, conv_thr, ofs_running); } ModuleBase::WARNING_QUIT("line_search", "ls_step <0"); __builtin_unreachable(); @@ -194,7 +195,7 @@ void Line_Search::update_brent(const double x, const double y, const double f) } } -bool Line_Search::brent(const double x, const double y, const double f, double& xnew, const double conv_thr) +bool Line_Search::brent(const double x, const double y, const double f, double& xnew, const double conv_thr, std::ofstream& ofs_running) { ls_step++; @@ -288,7 +289,7 @@ bool Line_Search::brent(const double x, const double y, const double f, double& // search steps I feel if the line search does not converge, we'd better change the direction // and restart line search { - GlobalV::ofs_running << "Too many Brent steps, let's do next CG step" << std::endl; + ofs_running << "Too many Brent steps, let's do next CG step" << std::endl; return true; // ModuleBase::WARNING_QUIT("Brent","too many steps in line search, something wrong"); } @@ -396,7 +397,7 @@ bool Line_Search::brent(const double x, const double y, const double f, double& } if (ls_step == 4) { - GlobalV::ofs_running << "Too many Brent steps, let's do next CG step" << std::endl; + ofs_running << "Too many Brent steps, let's do next CG step" << std::endl; return true; } return false; diff --git a/source/source_relax/line_search.h b/source/source_relax/line_search.h index 8277c319234..35794d379af 100644 --- a/source/source_relax/line_search.h +++ b/source/source_relax/line_search.h @@ -1,6 +1,8 @@ #ifndef LINE_SEARCH_H #define LINE_SEARCH_H +#include + class Line_Search { public: @@ -12,7 +14,8 @@ class Line_Search const double y, // value of function at x const double f, // gradient of function at x double& xnew, // postion where function has to be evaluated - const double conv_thr); // predicted change of function value of function at xnew + const double conv_thr, // predicted change of function value of function at xnew + std::ofstream& ofs_running); bool first_order(const double x, const double y, const double f, double& xnew); @@ -22,7 +25,7 @@ class Line_Search void update_brent(const double x, const double y, const double f); - bool brent(const double x, const double y, const double f, double& xnew, const double conv_thr); + bool brent(const double x, const double y, const double f, double& xnew, const double conv_thr, std::ofstream& ofs_running); private: int ls_step = 0; // step of line search diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index 429e8687844..f4d72173331 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -11,7 +11,8 @@ void Relax_Driver::relax_driver( ModuleESolver::ESolver* p_esolver, UnitCell& ucell, - const Input_para& inp) + const Input_para& inp, + std::ofstream& ofs_running) { ModuleBase::TITLE("Relax_Driver", "relax_driver"); ModuleBase::timer::start("Relax_Driver", "relax_driver"); @@ -34,7 +35,7 @@ void Relax_Driver::relax_driver( this->iter_info(steps, inp); this->esolve(steps[0], p_esolver, ucell, inp, force, stress, etot); - bool converged = this->relax_step(steps, p_esolver, ucell, inp, force, stress, etot); + bool converged = this->relax_step(steps, p_esolver, ucell, inp, force, stress, etot, ofs_running); this->json_out(p_esolver, ucell, inp, force, stress); // Check stop conditions @@ -43,7 +44,7 @@ void Relax_Driver::relax_driver( // Relaxation converged, exit loop immediately break; } - else if (ModuleIO::read_exit_file(GlobalV::MY_RANK, "EXIT", GlobalV::ofs_running)) + else if (ModuleIO::read_exit_file(GlobalV::MY_RANK, "EXIT", ofs_running)) { // EXIT file detected, exit loop break; @@ -119,7 +120,8 @@ bool Relax_Driver::relax_step(std::vector& steps, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress, - const double etot) + const double etot, + std::ofstream& ofs_running) { // Guard: For non-relaxation calculations (scf, nscf, etc.), return true immediately // to ensure the main loop exits after one iteration. This provides robustness @@ -133,7 +135,7 @@ bool Relax_Driver::relax_step(std::vector& steps, if (inp.relax_new) { - converged = this->rl.relax_step(ucell, force, stress, etot); + converged = this->rl.relax_step(ucell, force, stress, etot, ofs_running); // stress step +1 steps[2]++; // fix force step to 1 @@ -142,12 +144,12 @@ bool Relax_Driver::relax_step(std::vector& steps, else { converged = this->rl_old.relax_step(steps[0]+1, etot, ucell, force, - stress, steps[1], steps[2]); + stress, steps[1], steps[2], ofs_running); } this->stru_out(steps[0]+1, ucell, inp); - ModuleIO::output_after_relax(converged, p_esolver->conv_esolver, GlobalV::ofs_running); + ModuleIO::output_after_relax(converged, p_esolver->conv_esolver, ofs_running); return converged; } diff --git a/source/source_relax/relax_driver.h b/source/source_relax/relax_driver.h index 9e045dd2fe8..8348a2d4f75 100644 --- a/source/source_relax/relax_driver.h +++ b/source/source_relax/relax_driver.h @@ -8,6 +8,7 @@ #include "source_io/module_parameter/input_parameter.h" #include "source_base/matrix.h" #include +#include /** * @brief Driver class for geometry relaxation calculations. @@ -32,10 +33,12 @@ class Relax_Driver * @param p_esolver Pointer to the energy solver. * @param ucell Reference to the unit cell to be relaxed. * @param inp Input parameters for the calculation. + * @param ofs_running Output stream for running log. */ void relax_driver(ModuleESolver::ESolver* p_esolver, UnitCell& ucell, - const Input_para& inp); + const Input_para& inp, + std::ofstream& ofs_running); private: /// New relaxation optimizer (Relax class) @@ -83,11 +86,12 @@ class Relax_Driver * @param force Matrix of calculated forces. * @param stress Matrix of calculated stress. * @param etot Total energy. + * @param ofs_running Output stream for running log. * @return True if relaxation converged, false otherwise. */ bool relax_step(std::vector& steps, ModuleESolver::ESolver* p_esolver, UnitCell& ucell, const Input_para& inp, const ModuleBase::matrix& force, const ModuleBase::matrix& stress, - const double etot); + const double etot, std::ofstream& ofs_running); /** * @brief Output structure files after relaxation step. diff --git a/source/source_relax/relax_nsync.cpp b/source/source_relax/relax_nsync.cpp index 4b8a1355004..14e900b1fb1 100644 --- a/source/source_relax/relax_nsync.cpp +++ b/source/source_relax/relax_nsync.cpp @@ -55,7 +55,8 @@ bool IonCellOptimizer::relax_step(const int& istep, ModuleBase::matrix force, ModuleBase::matrix stress, int& force_step, - int& stress_step) + int& stress_step, + std::ofstream& ofs_running) { ModuleBase::TITLE("IonCellOptimizer", "relax_step"); @@ -89,7 +90,7 @@ bool IonCellOptimizer::relax_step(const int& istep, assert(PARAM.inp.cal_force == 1); // Calculate and apply atomic movement - IMM.cal_movement(istep, force_step, force, energy, ucell, GlobalV::ofs_running); + IMM.cal_movement(istep, force_step, force, energy, ucell, ofs_running); ++force_step; // Check convergence @@ -118,7 +119,7 @@ bool IonCellOptimizer::relax_step(const int& istep, assert(PARAM.inp.cal_stress == 1); // Calculate and apply lattice change - LCM.cal_lattice_change(istep, stress_step, stress, energy, ucell, GlobalV::ofs_running); + LCM.cal_lattice_change(istep, stress_step, stress, energy, ucell, ofs_running); bool converged = LCM.get_converged(); if (!converged) @@ -129,8 +130,8 @@ bool IonCellOptimizer::relax_step(const int& istep, ucell.cell_parameter_updated = true; // Update cell-related parameters after volume change - unitcell::setup_cell_after_vc(ucell, GlobalV::ofs_running); - ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SETUP UNITCELL"); + unitcell::setup_cell_after_vc(ucell, ofs_running); + ModuleBase::GlobalFunc::DONE(ofs_running, "SETUP UNITCELL"); } return converged; diff --git a/source/source_relax/relax_nsync.h b/source/source_relax/relax_nsync.h index 5fa76a4c71f..877718dd9b3 100644 --- a/source/source_relax/relax_nsync.h +++ b/source/source_relax/relax_nsync.h @@ -4,6 +4,7 @@ #include "ions_move_methods.h" #include "lattice_change_methods.h" #include "source_cell/unitcell.h" +#include /** * @class IonCellOptimizer @@ -15,8 +16,8 @@ * (for cell parameter updates). * * The optimization follows a sequential approach: - * 1. First perform atomic relaxation until convergence - * 2. Then perform cell relaxation (only in cell-relax mode) +1. First perform atomic relaxation until convergence +2. Then perform cell relaxation (only in cell-relax mode) */ class IonCellOptimizer { @@ -41,6 +42,7 @@ class IonCellOptimizer * @param stress Stress tensor matrix * @param force_step Current step counter for force-based relaxation * @param stress_step Current step counter for stress-based relaxation + * @param ofs_running Output stream for running log * @return true if relaxation is converged, false otherwise */ bool relax_step(const int& istep, @@ -49,7 +51,8 @@ class IonCellOptimizer ModuleBase::matrix force, ModuleBase::matrix stress, int& force_step, - int& stress_step); + int& stress_step, + std::ofstream& ofs_running); private: Ions_Move_Methods IMM; ///< Ionic movement methods for atom relaxation diff --git a/source/source_relax/relax_sync.cpp b/source/source_relax/relax_sync.cpp index ea6f5f5d866..9d6bfa0f97d 100644 --- a/source/source_relax/relax_sync.cpp +++ b/source/source_relax/relax_sync.cpp @@ -57,7 +57,8 @@ void Relax::init_relax(const int nat_in) bool Relax::relax_step(UnitCell& ucell, const ModuleBase::matrix& force, const ModuleBase::matrix& stress, - const double etot_in) + const double etot_in, + std::ofstream& ofs_running) { ModuleBase::TITLE("Relax", "relax_step"); @@ -67,7 +68,7 @@ bool Relax::relax_step(UnitCell& ucell, etot_p = etot; } - bool relax_done = this->setup_gradient(ucell, force, stress); + bool relax_done = this->setup_gradient(ucell, force, stress, ofs_running); if (relax_done) { return relax_done; @@ -79,13 +80,13 @@ bool Relax::relax_step(UnitCell& ucell, if (ls_done) { - this->new_direction(); - this->move_cell_ions(ucell, true); + this->new_direction(ofs_running); + this->move_cell_ions(ucell, true, ofs_running); } else { - this->perform_line_search(); - this->move_cell_ions(ucell, false); + this->perform_line_search(ofs_running); + this->move_cell_ions(ucell, false, ofs_running); dmovel = dmove; } @@ -94,7 +95,7 @@ bool Relax::relax_step(UnitCell& ucell, return relax_done; } -bool Relax::setup_gradient(const UnitCell& ucell, const ModuleBase::matrix& force, const ModuleBase::matrix& stress) +bool Relax::setup_gradient(const UnitCell& ucell, const ModuleBase::matrix& force, const ModuleBase::matrix& stress, std::ofstream& ofs_running) { ModuleBase::TITLE("Relax", "setup_gradient"); @@ -163,7 +164,7 @@ bool Relax::setup_gradient(const UnitCell& ucell, const ModuleBase::matrix& forc } - GlobalV::ofs_running << "\n Largest force is " << max_grad << + ofs_running << "\n Largest force is " << max_grad << " eV/Angstrom while threshold is " << PARAM.inp.force_thr_ev << " eV/Angstrom" << std::endl; //========================================= // set gradient for cell degrees of freedom @@ -248,16 +249,16 @@ bool Relax::setup_gradient(const UnitCell& ucell, const ModuleBase::matrix& forc force_converged = false; } - GlobalV::ofs_running << " Largest stress is " << largest_grad << " kbar while threshold is " << PARAM.inp.stress_thr << " kbar" << std::endl; + ofs_running << " Largest stress is " << largest_grad << " kbar while threshold is " << PARAM.inp.stress_thr << " kbar" << std::endl; } if (force_converged) { - GlobalV::ofs_running << "\n Relaxation is converged!" << std::endl; + ofs_running << "\n Relaxation is converged!" << std::endl; } else { - GlobalV::ofs_running << "\n Relaxation is not converged yet!" << std::endl; + ofs_running << "\n Relaxation is not converged yet!" << std::endl; } return force_converged; @@ -336,7 +337,7 @@ bool Relax::check_line_search() return true; } -void Relax::perform_line_search() +void Relax::perform_line_search(std::ofstream& ofs_running) { ModuleBase::TITLE("Relax", "line_search"); @@ -365,13 +366,13 @@ void Relax::perform_line_search() double x = dmovel, y = etot; double xnew = 0.0, yd = 0.0; - brent_done = this->ls.line_search(restart_brent, x, y, f, xnew, force_thr_eva); + brent_done = this->ls.line_search(restart_brent, x, y, f, xnew, force_thr_eva, ofs_running); dmove = xnew; return; } -void Relax::new_direction() +void Relax::new_direction(std::ofstream& ofs_running) { ModuleBase::TITLE("Relax", "new_direction"); if (cg_step != 0) @@ -452,7 +453,7 @@ void Relax::new_direction() // TODO: add a certain threshold for the progress. double xnew, yd = 1e-8; - this->ls.line_search(restart, x, y, f, xnew, yd); + this->ls.line_search(restart, x, y, f, xnew, yd, ofs_running); dmovel = 1.0; ltrial = true; @@ -461,7 +462,7 @@ void Relax::new_direction() return; } -void Relax::move_cell_ions(UnitCell& ucell, const bool is_new_dir) +void Relax::move_cell_ions(UnitCell& ucell, const bool is_new_dir, std::ofstream& ofs_running) { ModuleBase::TITLE("Relax", "move_cell_ions"); @@ -615,7 +616,7 @@ void Relax::move_cell_ions(UnitCell& ucell, const bool is_new_dir) unitcell::update_pos_taud(ucell.lat,move_ion.data(),ucell.ntype,ucell.nat,ucell.atoms); // Print the structure file. - unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,GlobalV::ofs_running); + unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,ofs_running); // ================================================================= // Step 4 : update G,GT and other stuff @@ -674,7 +675,7 @@ void Relax::move_cell_ions(UnitCell& ucell, const bool is_new_dir) // I do not want to change it if (if_cell_moves) { - unitcell::setup_cell_after_vc(ucell,GlobalV::ofs_running); - ModuleBase::GlobalFunc::DONE(GlobalV::ofs_running, "SETUP UNITCELL"); + unitcell::setup_cell_after_vc(ucell, ofs_running); + ModuleBase::GlobalFunc::DONE(ofs_running, "SETUP UNITCELL"); } } diff --git a/source/source_relax/relax_sync.h b/source/source_relax/relax_sync.h index b2631299132..c022d195b39 100644 --- a/source/source_relax/relax_sync.h +++ b/source/source_relax/relax_sync.h @@ -7,6 +7,7 @@ #include "source_base/matrix.h" #include "source_base/matrix3.h" #include "source_cell/unitcell.h" +#include class Relax { @@ -20,7 +21,8 @@ class Relax bool relax_step(UnitCell& ucell, const ModuleBase::matrix& force, const ModuleBase::matrix& stress, - const double etot_in); + const double etot_in, + std::ofstream& ofs_running); private: int istep = 0; // count ionic step @@ -29,19 +31,19 @@ class Relax // constraints are considered here // also check if relaxation has converged // based on threshold in force & stress - bool setup_gradient(const UnitCell& ucell, const ModuleBase::matrix& force, const ModuleBase::matrix& stress); + bool setup_gradient(const UnitCell& ucell, const ModuleBase::matrix& force, const ModuleBase::matrix& stress, std::ofstream& ofs_running); // check whether previous line search is done bool check_line_search(); // if line search not done : perform line search - void perform_line_search(); + void perform_line_search(std::ofstream& ofs_running); // if line search done: find new search direction and make a trial move - void new_direction(); + void new_direction(std::ofstream& ofs_running); // move ions and lattice vectors - void move_cell_ions(UnitCell& ucell, const bool is_new_dir); + void move_cell_ions(UnitCell& ucell, const bool is_new_dir, std::ofstream& ofs_running); int nat = 0; // number of atoms bool ltrial = false; // if last step is trial step diff --git a/source/source_relax/test/bfgs_test.cpp b/source/source_relax/test/bfgs_test.cpp index 081012dba39..4a8ddcf1195 100644 --- a/source/source_relax/test/bfgs_test.cpp +++ b/source/source_relax/test/bfgs_test.cpp @@ -13,6 +13,7 @@ #include "source_relax/ions_move_basic.h" // for Ions_Move_Basic static members #include "source_relax/relax_data.h" +#include /************************************************ * unit tests for Ions_Move_BFGS2 (no MockUnitCell) @@ -76,9 +77,11 @@ TEST_F(BFGSTest, RelaxStepAutoInitialize) force(0, 0) = 0.1; force(0, 1) = 0.0; force(0, 2) = 0.0; force(1, 0) = -0.1; force(1, 1) = 0.0; force(1, 2) = 0.0; + std::ofstream ofs_running; + // Before relax_step, is_initialized should be false EXPECT_FALSE(bfgs.is_initialized); - bfgs.relax_step(force, ucell); + bfgs.relax_step(force, ucell, ofs_running); // After relax_step, is_initialized should be true EXPECT_TRUE(bfgs.is_initialized); } @@ -230,7 +233,10 @@ TEST_F(BFGSTest, RelaxStepBasic) force(1, 0) = -0.1; force(1, 1) = 0.0; force(1, 2) = 0.0; // Allocate and call relax_step bfgs.allocate(ucell.nat); - bfgs.relax_step(force, ucell); + + std::ofstream ofs_running; + + bfgs.relax_step(force, ucell, ofs_running); // Check that ionic_position_updated is true EXPECT_TRUE(ucell.ionic_position_updated); // Check that force values are set (converted units) diff --git a/source/source_relax/test/ions_move_methods_test.cpp b/source/source_relax/test/ions_move_methods_test.cpp index 26a342eb0fe..f1aeb720f68 100644 --- a/source/source_relax/test/ions_move_methods_test.cpp +++ b/source/source_relax/test/ions_move_methods_test.cpp @@ -133,26 +133,27 @@ TEST_F(IonsMoveMethodsTest, CalMovement) const ModuleBase::matrix f(3, 3); const double etot = 0.0; UnitCell ucell; + std::ofstream ofs; Ions_Move_Basic::relax_method[0] = "bfgs"; Ions_Move_Basic::relax_method[1] = "1"; imm.allocate(natom, "bfgs", "1"); - imm.cal_movement(istep, force_step, f, etot, ucell); + imm.cal_movement(istep, force_step, f, etot, ucell, ofs); EXPECT_EQ(Ions_Move_Basic::istep, force_step); Ions_Move_Basic::relax_method[0] = "sd"; imm.allocate(natom, "sd", "1"); - imm.cal_movement(istep, force_step, f, etot, ucell); + imm.cal_movement(istep, force_step, f, etot, ucell, ofs); EXPECT_EQ(Ions_Move_Basic::istep, force_step); Ions_Move_Basic::relax_method[0] = "cg"; imm.allocate(natom, "cg", "1"); - imm.cal_movement(istep, force_step, f, etot, ucell); + imm.cal_movement(istep, force_step, f, etot, ucell, ofs); EXPECT_EQ(Ions_Move_Basic::istep, force_step); Ions_Move_Basic::relax_method[0] = "cg_bfgs"; imm.allocate(natom, "cg_bfgs", "1"); - imm.cal_movement(istep, force_step, f, etot, ucell); + imm.cal_movement(istep, force_step, f, etot, ucell, ofs); EXPECT_EQ(Ions_Move_Basic::istep, force_step); } @@ -164,12 +165,13 @@ TEST_F(IonsMoveMethodsTest, CalMovementWarningQuit) const ModuleBase::matrix f(3, 3); const double etot = 0.0; UnitCell ucell; + std::ofstream ofs; Ions_Move_Basic::relax_method[0] = "none"; Ions_Move_Basic::relax_method[1] = "1"; imm.allocate(natom, "none", "1"); GlobalV::ofs_warning.open("log"); - imm.cal_movement(istep, force_step, f, etot, ucell); + imm.cal_movement(istep, force_step, f, etot, ucell, ofs); GlobalV::ofs_warning.close(); std::ifstream ifs("log"); diff --git a/source/source_relax/test/line_search_test.cpp b/source/source_relax/test/line_search_test.cpp index b807e8ce237..97382e64193 100644 --- a/source/source_relax/test/line_search_test.cpp +++ b/source/source_relax/test/line_search_test.cpp @@ -1,6 +1,7 @@ #include "../line_search.h" #include +#include #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -27,6 +28,7 @@ class TestTO : public testing::Test void SetUp() { Line_Search ls; + std::ofstream ofs_running; double x, xnew, y, f; @@ -34,78 +36,78 @@ class TestTO : public testing::Test x = 0; y = 0; f = -2; - ls.line_search(1, x, y, f, xnew, 1e-10); + ls.line_search(1, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); x = 1; y = 0; f = 2; - ls.line_search(0, x, y, f, xnew, 1e-10); + ls.line_search(0, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); // 3rd order, harmonic, dmove < 0 x = 0; y = 0; f = 1; - ls.line_search(1, x, y, f, xnew, 1e-10); + ls.line_search(1, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); x = 1; y = 2; f = 3; - ls.line_search(0, x, y, f, xnew, 1e-10); + ls.line_search(0, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); // 3rd order, harmonic, dmove > 4 x = 0; y = 0; f = -20; - ls.line_search(1, x, y, f, xnew, 1e-10); + ls.line_search(1, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); x = 1; y = -9; f = -18; - ls.line_search(0, x, y, f, xnew, 1e-10); + ls.line_search(0, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); // 3rd order, anharmonic, use dmove1 & dmove x = 0; y = 0; f = -1; - ls.line_search(1, x, y, f, xnew, 1e-10); + ls.line_search(1, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); x = 1; y = 2; f = 3.5; - ls.line_search(0, x, y, f, xnew, 1e-10); + ls.line_search(0, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); // 3rd order, anharmonic, use dmove2 & dmoveh x = 0; y = 0; f = 4.5; - ls.line_search(1, x, y, f, xnew, 1e-10); + ls.line_search(1, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); x = 1; y = 2; f = -1; - ls.line_search(0, x, y, f, xnew, 1e-10); + ls.line_search(0, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); // 3rd order, anharmonic, dmoveh > 4 x = 0; y = 0; f = -20; - ls.line_search(1, x, y, f, xnew, 1e-10); + ls.line_search(1, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); x = 1; y = -5; f = -18; - ls.line_search(0, x, y, f, xnew, 1e-10); + ls.line_search(0, x, y, f, xnew, 1e-10, ofs_running); xnew_arr.push_back(xnew); } }; @@ -125,6 +127,7 @@ class TestLS : public testing::Test protected: std::vector xnew_arr; Line_Search ls; + std::ofstream ofs_running; double x = 0, xnew = 0; @@ -163,14 +166,14 @@ TEST_F(TestLS, LineSearch) if (i < 3) { - ls.line_search(restart, rand[ind], rand[ind + 1], rand[ind + 2], xnew, 1e-10); + ls.line_search(restart, rand[ind], rand[ind + 1], rand[ind + 2], xnew, 1e-10, ofs_running); ind = ind + 3; xnew_arr.push_back(xnew); } else { testing::internal::CaptureStdout(); - EXPECT_EXIT(ls.line_search(restart, rand[ind], rand[ind + 1], rand[ind + 2], xnew, 1e-10), + EXPECT_EXIT(ls.line_search(restart, rand[ind], rand[ind + 1], rand[ind + 2], xnew, 1e-10, ofs_running), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); diff --git a/source/source_relax/test/relax_test.cpp b/source/source_relax/test/relax_test.cpp index 16cd076bd5a..ed8689d1a63 100644 --- a/source/source_relax/test/relax_test.cpp +++ b/source/source_relax/test/relax_test.cpp @@ -16,6 +16,7 @@ class Test_SETGRAD : public testing::Test std::vector result; Input_para& input = PARAM.input; UnitCell ucell; + std::ofstream ofs; void SetUp() { @@ -84,7 +85,7 @@ class Test_SETGRAD : public testing::Test ucell.lc[2] = 1; rl.init_relax(nat); - rl.relax_step(ucell,force_in,stress_in,0.0); + rl.relax_step(ucell,force_in,stress_in,0.0, ofs); for(int i=0;i<3;i++) { @@ -98,14 +99,14 @@ class Test_SETGRAD : public testing::Test ucell.latvec.Identity(); input.fixed_axes = "shape"; rl.init_relax(nat); - rl.relax_step(ucell,force_in,stress_in,0.0); + rl.relax_step(ucell,force_in,stress_in,0.0, ofs); push_result(); //reset lattice vector ucell.latvec.Identity(); input.fixed_axes = "volume"; rl.init_relax(nat); - rl.relax_step(ucell,force_in,stress_in,0.0); + rl.relax_step(ucell,force_in,stress_in,0.0, ofs); push_result(); //reset lattice vector @@ -117,7 +118,7 @@ class Test_SETGRAD : public testing::Test ucell.lc[1] = 0; ucell.lc[2] = 0; rl.init_relax(nat); - rl.relax_step(ucell,force_in,stress_in,0.0); + rl.relax_step(ucell,force_in,stress_in,0.0, ofs); push_result(); } @@ -172,6 +173,7 @@ class Test_RELAX : public testing::Test Relax rl; std::vector result; UnitCell ucell; + std::ofstream ofs; void SetUp() { @@ -212,7 +214,7 @@ class Test_RELAX : public testing::Test energy_file >> energy; PARAM.input.fixed_ibrav = false; - rl.relax_step(ucell,force_in,stress_in,energy); + rl.relax_step(ucell,force_in,stress_in,energy, ofs); result.push_back(ucell.atoms[0].taud[0].x); result.push_back(ucell.atoms[0].taud[0].y); result.push_back(ucell.atoms[0].taud[0].z); From 29b5d38ab8ca46ab099956082fdfc23d62f77083 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Fri, 12 Jun 2026 17:33:25 +0800 Subject: [PATCH 39/50] update --- source/source_relax/ions_move_bfgs2.cpp | 21 ++++++++++--------- source/source_relax/ions_move_cg.cpp | 7 +++---- source/source_relax/ions_move_cg.h | 2 +- source/source_relax/ions_move_methods.cpp | 4 ++-- .../source_relax/test/ions_move_cg_test.cpp | 14 ++++++------- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/source/source_relax/ions_move_bfgs2.cpp b/source/source_relax/ions_move_bfgs2.cpp index bbd3167e416..53fafe4c801 100644 --- a/source/source_relax/ions_move_bfgs2.cpp +++ b/source/source_relax/ions_move_bfgs2.cpp @@ -87,16 +87,17 @@ void Ions_Move_BFGS2::relax_step(const ModuleBase::matrix& _force,UnitCell& ucel void Ions_Move_BFGS2::GetPos(UnitCell& ucell,std::vector>& pos) { assert(pos.size() == ucell.nat); - int k=0; + int iat=0; + const double scale = ModuleBase::BOHR_TO_A * ucell.lat0; for(int i=0;i>& pos_taud) { assert(pos_taud.size() == ucell.nat); - int k=0; + int iat=0; for(int i=0;i -using namespace Ions_Move_Basic; - double Ions_Move_CG::RELAX_CG_THR = -1.0; // default is 0.5 Ions_Move_CG::Ions_Move_CG() @@ -13,7 +11,7 @@ Ions_Move_CG::Ions_Move_CG() this->e0 = 0.0; } -void Ions_Move_CG::allocate(void) +void Ions_Move_CG::allocate(const int dim) { ModuleBase::TITLE("Ions_Move_CG", "allocate"); assert(dim > 0); @@ -28,7 +26,7 @@ void Ions_Move_CG::allocate(void) void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_CG", "start"); - assert(dim > 0); + assert(Ions_Move_Basic::dim > 0); static bool sd = false; static bool trial = false; @@ -44,6 +42,7 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const static double fmax = 0.0; static int nbrent = 0; + const int dim = Ions_Move_Basic::dim; std::vector pos(dim, 0.0); std::vector grad(dim, 0.0); std::vector cg_gradn(dim, 0.0); diff --git a/source/source_relax/ions_move_cg.h b/source/source_relax/ions_move_cg.h index bd1366c8d01..844c7452a68 100644 --- a/source/source_relax/ions_move_cg.h +++ b/source/source_relax/ions_move_cg.h @@ -14,7 +14,7 @@ class Ions_Move_CG : public CG_Base Ions_Move_CG(); ~Ions_Move_CG() = default; - void allocate(void); + void allocate(const int dim); void start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, std::ofstream& ofs); static double RELAX_CG_THR; diff --git a/source/source_relax/ions_move_methods.cpp b/source/source_relax/ions_move_methods.cpp index b22f15d7b24..4edaa663005 100644 --- a/source/source_relax/ions_move_methods.cpp +++ b/source/source_relax/ions_move_methods.cpp @@ -30,11 +30,11 @@ void Ions_Move_Methods::allocate(const int &natom, const std::string& relax_meth } else if (relax_method_0 == "cg") { - this->cg.allocate(); + this->cg.allocate(Ions_Move_Basic::dim); } else if (relax_method_0 == "cg_bfgs") { - this->cg.allocate(); + this->cg.allocate(Ions_Move_Basic::dim); this->bfgs.allocate(); } else if(relax_method_0 == "bfgs" && relax_method_1 == "1") diff --git a/source/source_relax/test/ions_move_cg_test.cpp b/source/source_relax/test/ions_move_cg_test.cpp index a811e66c9c4..49e1cb88d5b 100644 --- a/source/source_relax/test/ions_move_cg_test.cpp +++ b/source/source_relax/test/ions_move_cg_test.cpp @@ -20,7 +20,7 @@ class IonsMoveCGTest : public ::testing::Test // Initialize variables before each test Ions_Move_Basic::dim = 6; Ions_Move_Basic::update_iter = 5; - im_cg.allocate(); + im_cg.allocate(Ions_Move_Basic::dim); PARAM.input.force_thr = 0.001; // ban the 'cout' @@ -57,8 +57,8 @@ class IonsMoveCGTest : public ::testing::Test // Test whether the allocate() function can correctly allocate memory space TEST_F(IonsMoveCGTest, TestAllocate) { - Ions_Move_Basic::dim = 4; - im_cg.allocate(); + const int dim = 4; + im_cg.allocate(dim); // Check if allocated vectors are not empty EXPECT_EQ(im_cg.pos0.size(), 4U); @@ -70,15 +70,15 @@ TEST_F(IonsMoveCGTest, TestAllocate) // Test if a dimension less than or equal to 0 results in an assertion error TEST_F(IonsMoveCGTest, TestAllocateWithZeroDimension) { - Ions_Move_Basic::dim = 0; - ASSERT_DEATH(im_cg.allocate(), ""); + const int dim = 0; + ASSERT_DEATH(im_cg.allocate(dim), ""); } // Check that the arrays are correctly initialized to 0 TEST_F(IonsMoveCGTest, TestAllocateAndInitialize) { - Ions_Move_Basic::dim = 3; - im_cg.allocate(); + const int dim = 3; + im_cg.allocate(dim); // Check that the arrays are correctly initialized to 0 EXPECT_DOUBLE_EQ(0.0, im_cg.pos0[0]); From d5720cc1a32201126fadcc478b8f60bb929d6905 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Fri, 12 Jun 2026 17:51:47 +0800 Subject: [PATCH 40/50] move istep in ions_move_basic.h --- source/source_relax/ions_move_basic.cpp | 8 +-- source/source_relax/ions_move_basic.h | 7 +-- source/source_relax/ions_move_bfgs.cpp | 14 +++-- source/source_relax/ions_move_bfgs.h | 4 +- source/source_relax/ions_move_cg.cpp | 8 +-- source/source_relax/ions_move_cg.h | 2 +- source/source_relax/ions_move_methods.cpp | 10 ++-- source/source_relax/ions_move_sd.cpp | 16 +++--- source/source_relax/ions_move_sd.h | 4 +- .../test/ions_move_basic_test.cpp | 23 ++++---- .../source_relax/test/ions_move_bfgs_test.cpp | 22 +++++--- .../source_relax/test/ions_move_cg_test.cpp | 54 +++++++++---------- .../test/ions_move_methods_test.cpp | 4 -- .../source_relax/test/ions_move_sd_test.cpp | 24 ++++----- 14 files changed, 100 insertions(+), 100 deletions(-) diff --git a/source/source_relax/ions_move_basic.cpp b/source/source_relax/ions_move_basic.cpp index 03157644e56..2c7032cc284 100644 --- a/source/source_relax/ions_move_basic.cpp +++ b/source/source_relax/ions_move_basic.cpp @@ -181,13 +181,13 @@ void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, return; } -void Ions_Move_Basic::terminate(const UnitCell &ucell, std::ofstream& ofs) +void Ions_Move_Basic::terminate(const UnitCell &ucell, const int istep, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_Basic", "terminate"); if (Ions_Move_Basic::converged) { ofs << " end of geometry optimization" << std::endl; - ModuleBase::GlobalFunc::OUT(ofs, "istep", Ions_Move_Basic::istep); + ModuleBase::GlobalFunc::OUT(ofs, "istep", istep); ModuleBase::GlobalFunc::OUT(ofs, "update iteration", Ions_Move_Basic::update_iter); /* ofs<<"Saving the approximate inverse hessian"<grad.data(), ofs); } // use energy_in and istep to setup etot and etot_old. - Ions_Move_Basic::setup_etot(energy_in, false); + Ions_Move_Basic::setup_etot(energy_in, false, istep); // use gradient and etot and etot_old to check // if the result is converged. Ions_Move_Basic::check_converged(ucell, this->grad.data(), ofs); if (Ions_Move_Basic::converged) { - Ions_Move_Basic::terminate(ucell, ofs); + Ions_Move_Basic::terminate(ucell, istep, ofs); } else { @@ -81,7 +79,7 @@ void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con // calculate the new step -> the new move using hessian // matrix, and set the new trust radius. // [compute the move at last] - this->bfgs_routine(ucell.lat0, ofs); + this->bfgs_routine(ucell.lat0, istep, ofs); // get prepared for the next try. // even if the energy is higher, we save the information. @@ -168,7 +166,7 @@ void Ions_Move_BFGS::restart_bfgs(const double& lat0, std::ofstream& ofs) return; } -void Ions_Move_BFGS::bfgs_routine(const double& lat0, std::ofstream& ofs) +void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_BFGS", "bfgs_routine"); using namespace Ions_Move_Basic; @@ -301,7 +299,7 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0, std::ofstream& ofs) std::cout << " BFGS TRUST (Bohr) : " << trust_radius << std::endl; } - ModuleBase::GlobalFunc::OUT(ofs, "istep", Ions_Move_Basic::istep); + ModuleBase::GlobalFunc::OUT(ofs, "istep", istep); ModuleBase::GlobalFunc::OUT(ofs, "update iteration", Ions_Move_Basic::update_iter); // combine the direction and move length now diff --git a/source/source_relax/ions_move_bfgs.h b/source/source_relax/ions_move_bfgs.h index 6d75868165a..9ab6e6dfc53 100644 --- a/source/source_relax/ions_move_bfgs.h +++ b/source/source_relax/ions_move_bfgs.h @@ -13,11 +13,11 @@ class Ions_Move_BFGS : public BFGS_Basic ~Ions_Move_BFGS(); void allocate(void); - void start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, std::ofstream& ofs); + void start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, std::ofstream& ofs); private: bool init_done; - void bfgs_routine(const double& lat0, std::ofstream& ofs); + void bfgs_routine(const double& lat0, const int istep, std::ofstream& ofs); void restart_bfgs(const double& lat0, std::ofstream& ofs); bool first_step=true; // If it is the first step of the relaxation. The pos is only generated from ucell in the first step, and in the following steps, the pos is generated from the previous step. }; diff --git a/source/source_relax/ions_move_cg.cpp b/source/source_relax/ions_move_cg.cpp index 26ccd37b712..7416557f94f 100644 --- a/source/source_relax/ions_move_cg.cpp +++ b/source/source_relax/ions_move_cg.cpp @@ -23,7 +23,7 @@ void Ions_Move_CG::allocate(const int dim) this->e0 = 0.0; } -void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, std::ofstream& ofs) +void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, const int istep, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_CG", "start"); assert(Ions_Move_Basic::dim > 0); @@ -54,7 +54,7 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const while (true) { - if (Ions_Move_Basic::istep == 1) + if (istep == 1) { steplength = Ions_Move_Basic::relax_bfgs_init; sd = true; @@ -72,7 +72,7 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const } Ions_Move_Basic::setup_gradient(ucell, force, pos.data(), grad.data(), ofs); - Ions_Move_Basic::setup_etot(etot_in, 0); + Ions_Move_Basic::setup_etot(etot_in, 0, istep); if (flag == 0) { @@ -80,7 +80,7 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const } if (Ions_Move_Basic::converged) { - Ions_Move_Basic::terminate(ucell, ofs); + Ions_Move_Basic::terminate(ucell, istep, ofs); break; } diff --git a/source/source_relax/ions_move_cg.h b/source/source_relax/ions_move_cg.h index 844c7452a68..edcdf51cf79 100644 --- a/source/source_relax/ions_move_cg.h +++ b/source/source_relax/ions_move_cg.h @@ -15,7 +15,7 @@ class Ions_Move_CG : public CG_Base ~Ions_Move_CG() = default; void allocate(const int dim); - void start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, std::ofstream& ofs); + void start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, const int istep, std::ofstream& ofs); static double RELAX_CG_THR; int sd_step = 0; diff --git a/source/source_relax/ions_move_methods.cpp b/source/source_relax/ions_move_methods.cpp index 4edaa663005..b68543b93ce 100644 --- a/source/source_relax/ions_move_methods.cpp +++ b/source/source_relax/ions_move_methods.cpp @@ -61,26 +61,24 @@ void Ions_Move_Methods::cal_movement(const int &istep, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_Methods", "init"); - // Ions_Move_Basic::istep = istep; - Ions_Move_Basic::istep = force_step; if (Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] != "1") { // move_ions // output tau // check all symmery - bfgs.start(ucell, f, etot, ofs); + bfgs.start(ucell, f, etot, force_step, ofs); } else if (Ions_Move_Basic::relax_method[0] == "sd") { - sd.start(ucell, f, etot, ofs); + sd.start(ucell, f, etot, force_step, ofs); } else if (Ions_Move_Basic::relax_method[0] == "cg") { - cg.start(ucell, f, etot, ofs); + cg.start(ucell, f, etot, force_step, ofs); } else if (Ions_Move_Basic::relax_method[0] == "cg_bfgs") { - cg.start(ucell, f, etot, ofs); // added by pengfei 13-8-10 + cg.start(ucell, f, etot, force_step, ofs); // added by pengfei 13-8-10 } else if(Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] == "1") { diff --git a/source/source_relax/ions_move_sd.cpp b/source/source_relax/ions_move_sd.cpp index 8405d572d88..5727f01053a 100644 --- a/source/source_relax/ions_move_sd.cpp +++ b/source/source_relax/ions_move_sd.cpp @@ -20,7 +20,7 @@ void Ions_Move_SD::allocate() pos_saved.resize(dim, 0.0); } -void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot_in, std::ofstream& ofs) +void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot_in, const int istep, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_SD", "start"); @@ -35,8 +35,8 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const // 1: ediff = 0 // 0: ediff < 0 bool judgement = false; - setup_etot(etot_in, judgement); - setup_gradient(ucell, force, pos.data(), grad.data(), ofs); + Ions_Move_Basic::setup_etot(etot_in, judgement, istep); + Ions_Move_Basic::setup_gradient(ucell, force, pos.data(), grad.data(), ofs); if (istep == 1 || etot_in <= energy_saved) { @@ -64,11 +64,11 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const Ions_Move_Basic::check_converged(ucell, grad.data(), ofs); if (Ions_Move_Basic::converged) { - Ions_Move_Basic::terminate(ucell, ofs); + Ions_Move_Basic::terminate(ucell, istep, ofs); } else { - this->cal_tradius_sd(); + this->cal_tradius_sd(istep); for (int i = 0; i < dim; i++) { move[i] = -grad_saved[i] * trust_radius; @@ -80,15 +80,15 @@ void Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const return; } -void Ions_Move_SD::cal_tradius_sd() const +void Ions_Move_SD::cal_tradius_sd(const int istep) const { static int accepted_number = 0; - if (Ions_Move_Basic::istep == 1) + if (istep == 1) { Ions_Move_Basic::trust_radius = Ions_Move_Basic::relax_bfgs_init; } - else if (Ions_Move_Basic::istep > 1) + else if (istep > 1) { if (Ions_Move_Basic::ediff < 0.0) { diff --git a/source/source_relax/ions_move_sd.h b/source/source_relax/ions_move_sd.h index 69b3c30e6a9..4c718edcca7 100644 --- a/source/source_relax/ions_move_sd.h +++ b/source/source_relax/ions_move_sd.h @@ -14,14 +14,14 @@ class Ions_Move_SD ~Ions_Move_SD() = default; void allocate(void); - void start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot, std::ofstream& ofs); + void start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot, const int istep, std::ofstream& ofs); private: double energy_saved; std::vector pos_saved; std::vector grad_saved; - void cal_tradius_sd(void) const; + void cal_tradius_sd(const int istep) const; }; #endif diff --git a/source/source_relax/test/ions_move_basic_test.cpp b/source/source_relax/test/ions_move_basic_test.cpp index dd980d57f5a..0e2c59b2b13 100644 --- a/source/source_relax/test/ions_move_basic_test.cpp +++ b/source/source_relax/test/ions_move_basic_test.cpp @@ -220,12 +220,12 @@ TEST_F(IonsMoveBasicTest, TerminateConverged) { // Initialize data Ions_Move_Basic::converged = true; - Ions_Move_Basic::istep = 2; + const int istep = 2; Ions_Move_Basic::update_iter = 5; // Call the function being tested std::ofstream ofs("test_terminate_converged.log"); - Ions_Move_Basic::terminate(ucell, ofs); + Ions_Move_Basic::terminate(ucell, istep, ofs); ofs.close(); // Check the results @@ -245,10 +245,11 @@ TEST_F(IonsMoveBasicTest, TerminateNotConverged) { // Initialize data Ions_Move_Basic::converged = false; + const int istep = 10; // Call the function being tested std::ofstream ofs("test_terminate_not_converged.log"); - Ions_Move_Basic::terminate(ucell, ofs); + Ions_Move_Basic::terminate(ucell, istep, ofs); ofs.close(); // Check the results @@ -266,7 +267,7 @@ TEST_F(IonsMoveBasicTest, TerminateNotConverged) TEST_F(IonsMoveBasicTest, SetupEtotCase1) { // Initialize data - Ions_Move_Basic::istep = 1; + const int istep = 1; Ions_Move_Basic::etot_p = 1.0; Ions_Move_Basic::etot = 2.0; Ions_Move_Basic::ediff = 0.0; @@ -274,7 +275,7 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase1) bool judgement = true; // Call the function being tested - Ions_Move_Basic::setup_etot(energy_in, judgement); + Ions_Move_Basic::setup_etot(energy_in, judgement, istep); // Check the results EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot_p, 3.0); @@ -286,7 +287,7 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase1) TEST_F(IonsMoveBasicTest, SetupEtotCase2) { // Initialize data - Ions_Move_Basic::istep = 2; + const int istep = 2; Ions_Move_Basic::etot_p = 4.0; Ions_Move_Basic::etot = 2.0; Ions_Move_Basic::ediff = 0.0; @@ -294,7 +295,7 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase2) bool judgement = true; // Call the function being tested - Ions_Move_Basic::setup_etot(energy_in, judgement); + Ions_Move_Basic::setup_etot(energy_in, judgement, istep); // Check the results EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot_p, 3.0); @@ -306,7 +307,7 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase2) TEST_F(IonsMoveBasicTest, SetupEtotCase3) { // Initialize data - Ions_Move_Basic::istep = 2; + const int istep = 2; Ions_Move_Basic::etot_p = 1.0; Ions_Move_Basic::etot = 2.0; Ions_Move_Basic::ediff = 0.0; @@ -314,7 +315,7 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase3) bool judgement = true; // Call the function being tested - Ions_Move_Basic::setup_etot(energy_in, judgement); + Ions_Move_Basic::setup_etot(energy_in, judgement, istep); // Check the results EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot_p, 1.0); @@ -326,7 +327,7 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase3) TEST_F(IonsMoveBasicTest, SetupEtotCase4) { // Initialize data - Ions_Move_Basic::istep = 2; + const int istep = 2; Ions_Move_Basic::etot_p = 1.0; Ions_Move_Basic::etot = 2.0; Ions_Move_Basic::ediff = 0.0; @@ -334,7 +335,7 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase4) bool judgement = false; // Call the function being tested - Ions_Move_Basic::setup_etot(energy_in, judgement); + Ions_Move_Basic::setup_etot(energy_in, judgement, istep); // Check the results EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot_p, 2.0); diff --git a/source/source_relax/test/ions_move_bfgs_test.cpp b/source/source_relax/test/ions_move_bfgs_test.cpp index 2f8f3cbb549..79b27b280a8 100644 --- a/source/source_relax/test/ions_move_bfgs_test.cpp +++ b/source/source_relax/test/ions_move_bfgs_test.cpp @@ -68,13 +68,14 @@ TEST_F(IonsMoveBFGSTest, StartCase1) UnitCell ucell; ModuleBase::matrix force(2, 3); double energy_in = 0.0; + const int istep = 1; bfgs.init_done = false; bfgs.save_flag = true; // Call the function being tested bfgs.allocate(); std::ofstream ofs("test_start_case1.log"); - bfgs.start(ucell, force, energy_in, ofs); + bfgs.start(ucell, force, energy_in, istep, ofs); ofs.close(); // Check the results @@ -111,7 +112,7 @@ TEST_F(IonsMoveBFGSTest, StartCase2) PARAM.input.out_level = "ie"; // Initialize istep - Ions_Move_Basic::istep = 1; + const int istep = 1; ModuleBase::matrix force(2, 3); force(0, 0) = 10.0; @@ -122,7 +123,7 @@ TEST_F(IonsMoveBFGSTest, StartCase2) // Call the function being tested bfgs.allocate(); std::ofstream ofs("test_start_case2.log"); - bfgs.start(ucell, force, energy_in, ofs); + bfgs.start(ucell, force, energy_in, istep, ofs); ofs.close(); // Check the results @@ -229,6 +230,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase1) PARAM.input.test_relax_method = 1; PARAM.input.out_level = "ie"; double lat0 = 1.0; + const int istep = 1; Ions_Move_Basic::etot = 1.0; Ions_Move_Basic::etot_p = 0.9; Ions_Move_Basic::relax_bfgs_rmin = 1.0; @@ -242,7 +244,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase1) // Call the function being tested std::ofstream ofs("test_bfgs_routine_case1.log"); testing::internal::CaptureStdout(); - bfgs.bfgs_routine(lat0, ofs); + bfgs.bfgs_routine(lat0, istep, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -294,6 +296,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase2) PARAM.input.test_relax_method = 0; PARAM.input.out_level = "none"; double lat0 = 1.0; + const int istep = 1; Ions_Move_Basic::etot = 1.0; Ions_Move_Basic::etot_p = 0.9; Ions_Move_Basic::relax_bfgs_rmin = -1.0; @@ -307,7 +310,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase2) // Call the function being tested std::ofstream ofs("test_bfgs_routine_case2.log"); testing::internal::CaptureStdout(); - bfgs.bfgs_routine(lat0, ofs); + bfgs.bfgs_routine(lat0, istep, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -348,6 +351,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase3) { // Initilize data double lat0 = 1.0; + const int istep = 1; Ions_Move_Basic::etot = 0.9; Ions_Move_Basic::etot_p = 1.0; Ions_Move_Basic::update_iter = 0; @@ -366,7 +370,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase3) // Call the function being tested std::ofstream ofs("test_bfgs_routine_case3.log"); - bfgs.bfgs_routine(lat0, ofs); + bfgs.bfgs_routine(lat0, istep, ofs); ofs.close(); // Check the results @@ -411,6 +415,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit1) PARAM.input.test_relax_method = 1; PARAM.input.out_level = "ie"; double lat0 = 1.0; + const int istep = 1; Ions_Move_Basic::etot = 1.0; Ions_Move_Basic::etot_p = 0.9; Ions_Move_Basic::relax_bfgs_rmin = 1.0; @@ -424,7 +429,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit1) // Check the results std::ofstream ofs("test_bfgs_routine_warning_quit1.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.bfgs_routine(lat0, ofs), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.bfgs_routine(lat0, istep, ofs), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); ofs.close(); std::remove("test_bfgs_routine_warning_quit1.log"); @@ -441,6 +446,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit2) PARAM.input.test_relax_method = 1; PARAM.input.out_level = "ie"; double lat0 = 1.0; + const int istep = 1; Ions_Move_Basic::etot = 1.0; Ions_Move_Basic::etot_p = 0.9; Ions_Move_Basic::relax_bfgs_rmin = 1.0; @@ -448,7 +454,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit2) // Check the results std::ofstream ofs("test_bfgs_routine_warning_quit2.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.bfgs_routine(lat0, ofs), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.bfgs_routine(lat0, istep, ofs), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); ofs.close(); std::remove("test_bfgs_routine_warning_quit2.log"); diff --git a/source/source_relax/test/ions_move_cg_test.cpp b/source/source_relax/test/ions_move_cg_test.cpp index 49e1cb88d5b..0b648e14c22 100644 --- a/source/source_relax/test/ions_move_cg_test.cpp +++ b/source/source_relax/test/ions_move_cg_test.cpp @@ -91,7 +91,7 @@ TEST_F(IonsMoveCGTest, TestAllocateAndInitialize) TEST_F(IonsMoveCGTest, TestStartConverged) { // setup data - Ions_Move_Basic::istep = 1; + const int istep = 1; Ions_Move_Basic::converged = true; UnitCell ucell; setupucell(ucell); @@ -100,7 +100,7 @@ TEST_F(IonsMoveCGTest, TestStartConverged) // call function std::ofstream ofs("TestStartConverged.log"); - im_cg.start(ucell, force, etot, ofs); + im_cg.start(ucell, force, etot, istep, ofs); ofs.close(); // Check output @@ -126,7 +126,7 @@ TEST_F(IonsMoveCGTest, TestStartConverged) TEST_F(IonsMoveCGTest, TestStartSd) { // setup data - Ions_Move_Basic::istep = 1; + const int istep = 1; Ions_Move_Basic::converged = false; Ions_Move_Basic::relax_method[0] = "cg_bfgs"; Ions_Move_CG::RELAX_CG_THR = 100.0; @@ -138,7 +138,7 @@ TEST_F(IonsMoveCGTest, TestStartSd) // call function std::ofstream ofs("TestStartSd.log"); - im_cg.start(ucell, force, etot, ofs); + im_cg.start(ucell, force, etot, istep, ofs); ofs.close(); // Check output @@ -162,7 +162,7 @@ TEST_F(IonsMoveCGTest, TestStartSd) TEST_F(IonsMoveCGTest, TestStartTrialGoto) { // setup data - Ions_Move_Basic::istep = 1; + const int istep = 1; Ions_Move_Basic::converged = false; UnitCell ucell; setupucell(ucell); @@ -173,14 +173,14 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartTrialGoto_temp1.log"); - im_cg.start(ucell, force, etot, ofs1); + im_cg.start(ucell, force, etot, istep, ofs1); ofs1.close(); std::remove("TestStartTrialGoto_temp1.log"); - Ions_Move_Basic::istep = 2; + int istep_2 = 2; im_cg.move0[0] = 10.0; force(0, 0) = 0.001; std::ofstream ofs("TestStartTrialGoto.log"); - im_cg.start(ucell, force, etot, ofs); + im_cg.start(ucell, force, etot, istep, ofs); ofs.close(); // Check output @@ -204,7 +204,7 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) TEST_F(IonsMoveCGTest, TestStartTrial) { // setup data - Ions_Move_Basic::istep = 1; + const int istep = 1; Ions_Move_Basic::converged = false; UnitCell ucell; setupucell(ucell); @@ -215,13 +215,13 @@ TEST_F(IonsMoveCGTest, TestStartTrial) // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartTrial_temp1.log"); - im_cg.start(ucell, force, etot, ofs1); + im_cg.start(ucell, force, etot, istep, ofs1); ofs1.close(); std::remove("TestStartTrial_temp1.log"); - Ions_Move_Basic::istep = 2; + int istep_2 = 2; im_cg.move0[0] = 10.0; std::ofstream ofs("TestStartTrial.log"); - im_cg.start(ucell, force, etot, ofs); + im_cg.start(ucell, force, etot, istep, ofs); ofs.close(); // Check output @@ -245,7 +245,7 @@ TEST_F(IonsMoveCGTest, TestStartTrial) TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) { // setup data - Ions_Move_Basic::istep = 1; + const int istep = 1; Ions_Move_Basic::converged = false; UnitCell ucell; setupucell(ucell); @@ -256,18 +256,18 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrialGotoCase1_temp1.log"); - im_cg.start(ucell, force, etot, ofs1); + im_cg.start(ucell, force, etot, istep, ofs1); ofs1.close(); std::remove("TestStartNoTrialGotoCase1_temp1.log"); - Ions_Move_Basic::istep = 2; + int istep_2 = 2; std::ofstream ofs2("TestStartNoTrialGotoCase1_temp2.log"); - im_cg.start(ucell, force, etot, ofs2); + im_cg.start(ucell, force, etot, istep, ofs2); ofs2.close(); std::remove("TestStartNoTrialGotoCase1_temp2.log"); im_cg.move0[0] = 1.0; force(0, 0) = 0.001; std::ofstream ofs("TestStartNoTrialGotoCase1.log"); - im_cg.start(ucell, force, etot, ofs); + im_cg.start(ucell, force, etot, istep, ofs); ofs.close(); // Check output @@ -291,7 +291,7 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) { // setup data - Ions_Move_Basic::istep = 1; + const int istep = 1; Ions_Move_Basic::converged = false; UnitCell ucell; setupucell(ucell); @@ -302,17 +302,17 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrialGotoCase2_temp1.log"); - im_cg.start(ucell, force, etot, ofs1); + im_cg.start(ucell, force, etot, istep, ofs1); ofs1.close(); std::remove("TestStartNoTrialGotoCase2_temp1.log"); - Ions_Move_Basic::istep = 2; + int istep_2 = 2; im_cg.move0[0] = 10.0; std::ofstream ofs2("TestStartNoTrialGotoCase2_temp2.log"); - im_cg.start(ucell, force, etot, ofs2); + im_cg.start(ucell, force, etot, istep, ofs2); ofs2.close(); std::remove("TestStartNoTrialGotoCase2_temp2.log"); std::ofstream ofs("TestStartNoTrialGotoCase2.log"); - im_cg.start(ucell, force, etot, ofs); + im_cg.start(ucell, force, etot, istep, ofs); ofs.close(); // Check output @@ -336,7 +336,7 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) TEST_F(IonsMoveCGTest, TestStartNoTrial) { // setup data - Ions_Move_Basic::istep = 1; + const int istep = 1; Ions_Move_Basic::converged = false; UnitCell ucell; setupucell(ucell); @@ -347,18 +347,18 @@ TEST_F(IonsMoveCGTest, TestStartNoTrial) // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrial_temp1.log"); - im_cg.start(ucell, force, etot, ofs1); + im_cg.start(ucell, force, etot, istep, ofs1); ofs1.close(); std::remove("TestStartNoTrial_temp1.log"); - Ions_Move_Basic::istep = 2; + int istep_2 = 2; im_cg.move0[0] = 1.0; force(0, 0) = 0.001; std::ofstream ofs2("TestStartNoTrial_temp2.log"); - im_cg.start(ucell, force, etot, ofs2); + im_cg.start(ucell, force, etot, istep, ofs2); ofs2.close(); std::remove("TestStartNoTrial_temp2.log"); std::ofstream ofs("TestStartNoTrial.log"); - im_cg.start(ucell, force, etot, ofs); + im_cg.start(ucell, force, etot, istep, ofs); ofs.close(); // Check output diff --git a/source/source_relax/test/ions_move_methods_test.cpp b/source/source_relax/test/ions_move_methods_test.cpp index f1aeb720f68..725fdaa327c 100644 --- a/source/source_relax/test/ions_move_methods_test.cpp +++ b/source/source_relax/test/ions_move_methods_test.cpp @@ -139,22 +139,18 @@ TEST_F(IonsMoveMethodsTest, CalMovement) Ions_Move_Basic::relax_method[1] = "1"; imm.allocate(natom, "bfgs", "1"); imm.cal_movement(istep, force_step, f, etot, ucell, ofs); - EXPECT_EQ(Ions_Move_Basic::istep, force_step); Ions_Move_Basic::relax_method[0] = "sd"; imm.allocate(natom, "sd", "1"); imm.cal_movement(istep, force_step, f, etot, ucell, ofs); - EXPECT_EQ(Ions_Move_Basic::istep, force_step); Ions_Move_Basic::relax_method[0] = "cg"; imm.allocate(natom, "cg", "1"); imm.cal_movement(istep, force_step, f, etot, ucell, ofs); - EXPECT_EQ(Ions_Move_Basic::istep, force_step); Ions_Move_Basic::relax_method[0] = "cg_bfgs"; imm.allocate(natom, "cg_bfgs", "1"); imm.cal_movement(istep, force_step, f, etot, ucell, ofs); - EXPECT_EQ(Ions_Move_Basic::istep, force_step); } // Test the cal_movement() function warning quit diff --git a/source/source_relax/test/ions_move_sd_test.cpp b/source/source_relax/test/ions_move_sd_test.cpp index 328cb831c40..88aadbc1fc3 100644 --- a/source/source_relax/test/ions_move_sd_test.cpp +++ b/source/source_relax/test/ions_move_sd_test.cpp @@ -67,7 +67,7 @@ TEST_F(IonsMoveSDTest, TestAllocateAndInitialize) TEST_F(IonsMoveSDTest, TestStartConverged) { // setup data - Ions_Move_Basic::istep = 1; + const int istep = 1; Ions_Move_Basic::converged = true; UnitCell ucell; ModuleBase::matrix force(2, 3); @@ -75,7 +75,7 @@ TEST_F(IonsMoveSDTest, TestStartConverged) // call function std::ofstream ofs("test_sd_start_converged.log"); - im_sd.start(ucell, force, etot, ofs); + im_sd.start(ucell, force, etot, istep, ofs); ofs.close(); // Check output @@ -107,7 +107,7 @@ TEST_F(IonsMoveSDTest, TestStartConverged) TEST_F(IonsMoveSDTest, TestStartNotConverged) { // setup data - Ions_Move_Basic::istep = 1; + const int istep = 1; Ions_Move_Basic::converged = true; UnitCell ucell; ModuleBase::matrix force(2, 3); @@ -128,7 +128,7 @@ TEST_F(IonsMoveSDTest, TestStartNotConverged) // call function std::ofstream ofs("test_sd_start_not_converged.log"); - im_sd.start(ucell, force, etot, ofs); + im_sd.start(ucell, force, etot, istep, ofs); ofs.close(); // Check output @@ -162,12 +162,12 @@ TEST_F(IonsMoveSDTest, TestStartNotConverged) TEST_F(IonsMoveSDTest, CalTradiusSdCase1) { // setup data - Ions_Move_Basic::istep = 1; + const int istep = 1; PARAM.input.out_level = "ie"; // call function testing::internal::CaptureStdout(); - im_sd.cal_tradius_sd(); + im_sd.cal_tradius_sd(istep); std::string std_outout = testing::internal::GetCapturedStdout(); // Check the results @@ -180,12 +180,12 @@ TEST_F(IonsMoveSDTest, CalTradiusSdCase1) TEST_F(IonsMoveSDTest, CalTradiusSdCase2) { // setup data - Ions_Move_Basic::istep = 2; + const int istep = 2; Ions_Move_Basic::ediff = -1.0; PARAM.input.out_level = "m"; // call function - im_sd.cal_tradius_sd(); + im_sd.cal_tradius_sd(istep); // Check the results EXPECT_EQ(Ions_Move_Basic::trust_radius, -1.0); @@ -195,12 +195,12 @@ TEST_F(IonsMoveSDTest, CalTradiusSdCase2) TEST_F(IonsMoveSDTest, CalTradiusSdCase3) { // setup data - Ions_Move_Basic::istep = 2; + const int istep = 2; Ions_Move_Basic::ediff = 1.0; PARAM.input.out_level = "m"; // call function - im_sd.cal_tradius_sd(); + im_sd.cal_tradius_sd(istep); // Check the results EXPECT_EQ(Ions_Move_Basic::trust_radius, -0.5); @@ -210,11 +210,11 @@ TEST_F(IonsMoveSDTest, CalTradiusSdCase3) TEST_F(IonsMoveSDTest, CalTradiusWraningQuit) { // setup data - Ions_Move_Basic::istep = 0; + const int istep = 0; // Check the results testing::internal::CaptureStdout(); - EXPECT_EXIT(im_sd.cal_tradius_sd(), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(im_sd.cal_tradius_sd(istep), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("istep < 1!")); } From 55f198a4f8cd8c3f2f66db9322ee80949bea7fc3 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Fri, 12 Jun 2026 21:04:40 +0800 Subject: [PATCH 41/50] remove converged variable in ions_move_basic --- source/source_relax/ions_move_basic.cpp | 14 ++++----- source/source_relax/ions_move_basic.h | 7 +++-- source/source_relax/ions_move_bfgs.cpp | 11 ++++--- source/source_relax/ions_move_bfgs.h | 2 +- source/source_relax/ions_move_bfgs2.cpp | 10 +++--- source/source_relax/ions_move_bfgs2.h | 4 +-- source/source_relax/ions_move_cg.cpp | 19 ++++++------ source/source_relax/ions_move_cg.h | 2 +- source/source_relax/ions_move_lbfgs.cpp | 9 +++--- source/source_relax/ions_move_lbfgs.h | 8 ++--- source/source_relax/ions_move_methods.cpp | 13 ++++---- source/source_relax/ions_move_methods.h | 4 ++- source/source_relax/ions_move_sd.cpp | 12 +++---- source/source_relax/ions_move_sd.h | 2 +- source/source_relax/lattice_change_basic.cpp | 18 +++++------ source/source_relax/lattice_change_basic.h | 7 +++-- source/source_relax/lattice_change_cg.cpp | 19 ++++++------ source/source_relax/lattice_change_cg.h | 2 +- .../source_relax/lattice_change_methods.cpp | 2 +- source/source_relax/lattice_change_methods.h | 3 +- source/source_relax/relax_data.cpp | 2 +- source/source_relax/relax_data.h | 2 +- .../test/ions_move_basic_test.cpp | 20 ++++++------ .../source_relax/test/ions_move_cg_test.cpp | 14 --------- .../test/ions_move_methods_test.cpp | 6 ---- .../source_relax/test/ions_move_sd_test.cpp | 4 --- .../test/lattice_change_basic_test.cpp | 31 +++++++++---------- .../test/lattice_change_cg_test.cpp | 1 - .../test/lattice_change_methods_test.cpp | 9 +++--- 29 files changed, 115 insertions(+), 142 deletions(-) diff --git a/source/source_relax/ions_move_basic.cpp b/source/source_relax/ions_move_basic.cpp index 2c7032cc284..38849ce75aa 100644 --- a/source/source_relax/ions_move_basic.cpp +++ b/source/source_relax/ions_move_basic.cpp @@ -111,7 +111,7 @@ void Ions_Move_Basic::move_atoms(UnitCell &ucell, double *move, double *pos, std return; } -void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, std::ofstream& ofs) +bool Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_Basic", "check_converged"); assert(dim > 0); @@ -158,7 +158,7 @@ void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, { ofs << " largest force is 0, no movement is possible." << std::endl; ofs << " it may converged, otherwise no movement of atom is allowed." << std::endl; - Ions_Move_Basic::converged = true; + return true; } // mohan update 2011-04-21 else if (etot_diff < etot_thr && Ions_Move_Basic::largest_grad < PARAM.inp.force_thr ) @@ -166,8 +166,8 @@ void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, ofs << "\n Ion relaxation is converged!" << std::endl; ofs << "\n Energy difference (Ry) = " << etot_diff << std::endl; - Ions_Move_Basic::converged = true; ++Ions_Move_Basic::update_iter; + return true; } else { @@ -175,16 +175,14 @@ void Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, << PARAM.inp.force_thr * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A << ")" << std::endl; // std::cout << "\n etot_diff=" << etot_diff << " etot_thr=" << etot_thr //<< " largest_grad=" << largest_grad << " force_thr=" << PARAM.inp.force_thr << std::endl; - Ions_Move_Basic::converged = false; + return false; } - - return; } -void Ions_Move_Basic::terminate(const UnitCell &ucell, const int istep, std::ofstream& ofs) +void Ions_Move_Basic::terminate(const bool converged, const UnitCell &ucell, const int istep, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_Basic", "terminate"); - if (Ions_Move_Basic::converged) + if (converged) { ofs << " end of geometry optimization" << std::endl; ModuleBase::GlobalFunc::OUT(ofs, "istep", istep); diff --git a/source/source_relax/ions_move_basic.h b/source/source_relax/ions_move_basic.h index e887133fa85..54b84268930 100644 --- a/source/source_relax/ions_move_basic.h +++ b/source/source_relax/ions_move_basic.h @@ -20,7 +20,6 @@ namespace Ions_Move_Basic { // Shared state variables (referenced from Relax_Data for unified data sharing) static int& dim = Relax_Data::dim; ///< Dimension of free variables (3 * number of atoms) -static bool& converged = Relax_Data::converged; ///< Convergence flag static double& largest_grad = Relax_Data::largest_grad; ///< Largest gradient component static double& ediff = Relax_Data::ediff; ///< Energy difference from previous step static double& etot = Relax_Data::etot; ///< Total energy of current step @@ -61,16 +60,18 @@ void move_atoms(UnitCell &ucell, double *move, double *pos, std::ofstream& ofs); * @param ucell Unit cell containing lattice information * @param grad Gradient array (dimension: dim) * @param ofs Output stream for logging + * @return true if converged, false otherwise */ -void check_converged(const UnitCell &ucell, const double *grad, std::ofstream& ofs); +bool check_converged(const UnitCell &ucell, const double *grad, std::ofstream& ofs); /** * @brief Terminate geometry optimization and output results. + * @param converged Convergence flag * @param ucell Unit cell to output * @param istep Current ionic step index * @param ofs Output stream for logging */ -void terminate(const UnitCell &ucell, const int istep, std::ofstream& ofs); +void terminate(const bool converged, const UnitCell &ucell, const int istep, std::ofstream& ofs); /** * @brief Update energy values and compute energy difference. diff --git a/source/source_relax/ions_move_bfgs.cpp b/source/source_relax/ions_move_bfgs.cpp index 54b88dc9e4c..885ee9c0682 100644 --- a/source/source_relax/ions_move_bfgs.cpp +++ b/source/source_relax/ions_move_bfgs.cpp @@ -37,7 +37,7 @@ void Ions_Move_BFGS::allocate() return; } -void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, std::ofstream& ofs) +bool Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_BFGS", "start"); @@ -58,11 +58,12 @@ void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con Ions_Move_Basic::setup_etot(energy_in, false, istep); // use gradient and etot and etot_old to check // if the result is converged. - Ions_Move_Basic::check_converged(ucell, this->grad.data(), ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, this->grad.data(), ofs); - if (Ions_Move_Basic::converged) + if (converged) { - Ions_Move_Basic::terminate(ucell, istep, ofs); + Ions_Move_Basic::terminate(converged, ucell, istep, ofs); + return true; } else { @@ -86,8 +87,8 @@ void Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con this->save_bfgs(); Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data(), ofs); + return false; } - return; } void Ions_Move_BFGS::restart_bfgs(const double& lat0, std::ofstream& ofs) diff --git a/source/source_relax/ions_move_bfgs.h b/source/source_relax/ions_move_bfgs.h index 9ab6e6dfc53..74d72e5cf69 100644 --- a/source/source_relax/ions_move_bfgs.h +++ b/source/source_relax/ions_move_bfgs.h @@ -13,7 +13,7 @@ class Ions_Move_BFGS : public BFGS_Basic ~Ions_Move_BFGS(); void allocate(void); - void start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, std::ofstream& ofs); + bool start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, std::ofstream& ofs); private: bool init_done; diff --git a/source/source_relax/ions_move_bfgs2.cpp b/source/source_relax/ions_move_bfgs2.cpp index 53fafe4c801..ee136cac69c 100644 --- a/source/source_relax/ions_move_bfgs2.cpp +++ b/source/source_relax/ions_move_bfgs2.cpp @@ -34,7 +34,7 @@ void Ions_Move_BFGS2::allocate(const int _size) } -void Ions_Move_BFGS2::relax_step(const ModuleBase::matrix& _force,UnitCell& ucell, std::ofstream& ofs_running) +bool Ions_Move_BFGS2::relax_step(const ModuleBase::matrix& _force,UnitCell& ucell, std::ofstream& ofs_running) { if(!is_initialized) { @@ -79,9 +79,10 @@ void Ions_Move_BFGS2::relax_step(const ModuleBase::matrix& _force,UnitCell& ucel this->DetermineStep(steplength,dpos,maxstep); this->UpdatePos(ucell); this->CalculateLargestGrad(_force,ucell); - this->IsRestrain(); + bool converged = this->IsRestrain(); // print out geometry information during bfgs_trad relax unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,ofs_running); + return converged; } void Ions_Move_BFGS2::GetPos(UnitCell& ucell,std::vector>& pos) @@ -362,8 +363,7 @@ void Ions_Move_BFGS2::CalculateLargestGrad(const ModuleBase::matrix& _force,Unit } } -void Ions_Move_BFGS2::IsRestrain() +bool Ions_Move_BFGS2::IsRestrain() { - Ions_Move_Basic::converged = largest_grad - * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A> 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 IsRestrain();//check if converged + bool 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); diff --git a/source/source_relax/ions_move_cg.cpp b/source/source_relax/ions_move_cg.cpp index 7416557f94f..6e87fc6b885 100644 --- a/source/source_relax/ions_move_cg.cpp +++ b/source/source_relax/ions_move_cg.cpp @@ -23,7 +23,7 @@ void Ions_Move_CG::allocate(const int dim) this->e0 = 0.0; } -void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, const int istep, std::ofstream& ofs) +bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, const int istep, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_CG", "start"); assert(Ions_Move_Basic::dim > 0); @@ -74,14 +74,15 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const Ions_Move_Basic::setup_gradient(ucell, force, pos.data(), grad.data(), ofs); Ions_Move_Basic::setup_etot(etot_in, 0, istep); + bool converged = false; if (flag == 0) { - Ions_Move_Basic::check_converged(ucell, grad.data(), ofs); + converged = Ions_Move_Basic::check_converged(ucell, grad.data(), ofs); } - if (Ions_Move_Basic::converged) + if (converged) { - Ions_Move_Basic::terminate(ucell, istep, ofs); - break; + Ions_Move_Basic::terminate(converged, ucell, istep, ofs); + return true; } if (sd) @@ -117,7 +118,7 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const } Ions_Move_Basic::relax_bfgs_init = xb; - break; + return false; } if (trial) @@ -151,7 +152,7 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const xc = xb + xc; xpt = xc; Ions_Move_Basic::relax_bfgs_init = xc; - break; + return false; } double xtemp = 0.0; @@ -184,8 +185,6 @@ void Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const CG_Base::setup_move(dim, move.data(), cg_gradn.data(), best_x); Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data(), ofs); Ions_Move_Basic::relax_bfgs_init = xc; - break; + return false; } - - return; } \ No newline at end of file diff --git a/source/source_relax/ions_move_cg.h b/source/source_relax/ions_move_cg.h index edcdf51cf79..7b25e5dd575 100644 --- a/source/source_relax/ions_move_cg.h +++ b/source/source_relax/ions_move_cg.h @@ -15,7 +15,7 @@ class Ions_Move_CG : public CG_Base ~Ions_Move_CG() = default; void allocate(const int dim); - void start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, const int istep, std::ofstream& ofs); + bool start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, const int istep, std::ofstream& ofs); static double RELAX_CG_THR; int sd_step = 0; diff --git a/source/source_relax/ions_move_lbfgs.cpp b/source/source_relax/ions_move_lbfgs.cpp index 39c554d7e90..339fad9baf2 100644 --- a/source/source_relax/ions_move_lbfgs.cpp +++ b/source/source_relax/ions_move_lbfgs.cpp @@ -25,7 +25,7 @@ void Ions_Move_LBFGS::allocate(const int _size) // initialize H0、H、pos0、fo //l_search.init_line_search(); } -void Ions_Move_LBFGS::relax_step(const ModuleBase::matrix _force,UnitCell& ucell,const double &etot, std::ofstream& ofs_running) +bool Ions_Move_LBFGS::relax_step(const ModuleBase::matrix _force,UnitCell& ucell,const double &etot, std::ofstream& ofs_running) { get_pos(ucell,pos); get_pos_taud(ucell,pos_taud); @@ -62,9 +62,10 @@ void Ions_Move_LBFGS::relax_step(const ModuleBase::matrix _force,UnitCell& ucell this->determine_step(steplength,dpos,maxstep); this->update_pos(ucell); this->calculate_largest_grad(_force,ucell); - this->is_restrain(); + bool converged = this->is_restrain(); // mohan add 2025-06-22 unitcell::print_tau(ucell.atoms,ucell.Coordinate,ucell.ntype,ucell.lat0,ofs_running); + return converged; } void Ions_Move_LBFGS::get_pos(UnitCell& ucell,std::vector>& pos) @@ -250,9 +251,9 @@ void Ions_Move_LBFGS::update_pos(UnitCell& ucell) unitcell::update_pos_tau(ucell.lat,a,ucell.ntype,ucell.nat,ucell.atoms); } -void Ions_Move_LBFGS::is_restrain() +bool Ions_Move_LBFGS::is_restrain() { - Ions_Move_Basic::converged = Ions_Move_Basic::largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_Ae0 = 0.0; } -void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs) +bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs) { ModuleBase::TITLE("Lattice_Change_CG", "start"); @@ -79,15 +79,16 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ Lattice_Change_Basic::setup_gradient(ucell, lat.data(), grad.data(), stress); Lattice_Change_Basic::setup_etot(etot_in, 0); + bool converged = false; if (flag == 0) { - Lattice_Change_Basic::check_converged(ucell, stress, grad.data(), ofs); + converged = Lattice_Change_Basic::check_converged(ucell, stress, grad.data(), ofs); } - if (Lattice_Change_Basic::converged) + if (converged) { - Lattice_Change_Basic::terminate(ofs); - break; + Lattice_Change_Basic::terminate(converged, ofs); + return true; } if (sd) @@ -113,7 +114,7 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ sd = false; Lattice_Change_Basic::lattice_change_ini = xb; - break; + return false; } if (trial) @@ -149,7 +150,7 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ xpt = xc; Lattice_Change_Basic::lattice_change_ini = xc; - break; + return false; } double xtemp = 0.0; @@ -184,8 +185,6 @@ void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ Lattice_Change_Basic::change_lattice(ucell, move.data(), lat.data()); Lattice_Change_Basic::lattice_change_ini = xc; - break; + return false; } - - return; } \ No newline at end of file diff --git a/source/source_relax/lattice_change_cg.h b/source/source_relax/lattice_change_cg.h index 6e10333c35e..07f77b618d9 100644 --- a/source/source_relax/lattice_change_cg.h +++ b/source/source_relax/lattice_change_cg.h @@ -15,7 +15,7 @@ class Lattice_Change_CG : public CG_Base ~Lattice_Change_CG() = default; void allocate(void); - void start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot, std::ofstream& ofs); + bool start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot, std::ofstream& ofs); private: std::vector lat0; diff --git a/source/source_relax/lattice_change_methods.cpp b/source/source_relax/lattice_change_methods.cpp index 72b3adcdd72..0fff33ba8f9 100644 --- a/source/source_relax/lattice_change_methods.cpp +++ b/source/source_relax/lattice_change_methods.cpp @@ -28,7 +28,7 @@ void Lattice_Change_Methods::cal_lattice_change(const int &istep, Lattice_Change_Basic::istep = istep; Lattice_Change_Basic::stress_step = stress_step; - lccg.start(ucell, stress, etot, ofs); + converged_ = lccg.start(ucell, stress, etot, ofs); return; } diff --git a/source/source_relax/lattice_change_methods.h b/source/source_relax/lattice_change_methods.h index bccafaeb7f1..6aad18c6833 100644 --- a/source/source_relax/lattice_change_methods.h +++ b/source/source_relax/lattice_change_methods.h @@ -23,7 +23,7 @@ class Lattice_Change_Methods bool get_converged(void) const { - return Lattice_Change_Basic::converged; + return converged_; } double get_ediff(void) const @@ -38,5 +38,6 @@ class Lattice_Change_Methods private: Lattice_Change_CG lccg; + bool converged_ = false; }; #endif diff --git a/source/source_relax/relax_data.cpp b/source/source_relax/relax_data.cpp index 98da0ce56a3..c464267bec6 100644 --- a/source/source_relax/relax_data.cpp +++ b/source/source_relax/relax_data.cpp @@ -2,7 +2,7 @@ int Relax_Data::dim = 0; int Relax_Data::dim_lattice = 0; -bool Relax_Data::converged = false; + double Relax_Data::largest_grad = 0.0; int Relax_Data::istep = 0; double Relax_Data::ediff = 0.0; diff --git a/source/source_relax/relax_data.h b/source/source_relax/relax_data.h index 2894a781adc..c5f2f5bf114 100644 --- a/source/source_relax/relax_data.h +++ b/source/source_relax/relax_data.h @@ -32,7 +32,7 @@ class Relax_Data { // Static members - shared global state across all relaxation instances static int dim; ///< Dimension of free variables (3 * number of atoms) for ion movement static int dim_lattice; ///< Dimension of free variables (9) for lattice change - static bool converged; ///< Convergence flag: true if optimization is converged + static double largest_grad; ///< Largest gradient component (force) in current step static int istep; ///< Current iteration step index static double ediff; ///< Energy difference from previous step (etot - etot_p) diff --git a/source/source_relax/test/ions_move_basic_test.cpp b/source/source_relax/test/ions_move_basic_test.cpp index 0e2c59b2b13..8e38958c46d 100644 --- a/source/source_relax/test/ions_move_basic_test.cpp +++ b/source/source_relax/test/ions_move_basic_test.cpp @@ -113,7 +113,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase1) // Call the function being tested std::ofstream ofs("test_check_converged_case1.log"); testing::internal::CaptureStdout(); - Ions_Move_Basic::check_converged(ucell, grad, ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -133,7 +133,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase1) EXPECT_THAT(ofs_output , ::testing::HasSubstr(expected_ofs)); EXPECT_EQ(expected_std, std_outout); EXPECT_EQ(Ions_Move_Basic::update_iter, 1); - EXPECT_EQ(Ions_Move_Basic::converged, true); + EXPECT_EQ(converged, true); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.0); } @@ -152,7 +152,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase2) // Call the function being tested std::ofstream ofs("test_check_converged_case2.log"); testing::internal::CaptureStdout(); - Ions_Move_Basic::check_converged(ucell, grad, ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -172,7 +172,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase2) EXPECT_THAT(ofs_output , ::testing::HasSubstr(expected_ofs)); EXPECT_EQ(expected_std, std_outout); EXPECT_EQ(Ions_Move_Basic::update_iter, 2); - EXPECT_EQ(Ions_Move_Basic::converged, true); + EXPECT_EQ(converged, true); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.1); } @@ -191,7 +191,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase3) // Call the function being tested std::ofstream ofs("test_check_converged_case3.log"); testing::internal::CaptureStdout(); - Ions_Move_Basic::check_converged(ucell, grad, ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -211,7 +211,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase3) EXPECT_THAT(ofs_output , ::testing::HasSubstr(expected_ofs)); EXPECT_EQ(expected_std, std_outout); EXPECT_EQ(Ions_Move_Basic::update_iter, 1); - EXPECT_EQ(Ions_Move_Basic::converged, false); + EXPECT_EQ(converged, false); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.1); } @@ -219,13 +219,13 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase3) TEST_F(IonsMoveBasicTest, TerminateConverged) { // Initialize data - Ions_Move_Basic::converged = true; + const bool converged = true; const int istep = 2; Ions_Move_Basic::update_iter = 5; // Call the function being tested std::ofstream ofs("test_terminate_converged.log"); - Ions_Move_Basic::terminate(ucell, istep, ofs); + Ions_Move_Basic::terminate(converged, ucell, istep, ofs); ofs.close(); // Check the results @@ -244,12 +244,12 @@ TEST_F(IonsMoveBasicTest, TerminateConverged) TEST_F(IonsMoveBasicTest, TerminateNotConverged) { // Initialize data - Ions_Move_Basic::converged = false; + const bool converged = false; const int istep = 10; // Call the function being tested std::ofstream ofs("test_terminate_not_converged.log"); - Ions_Move_Basic::terminate(ucell, istep, ofs); + Ions_Move_Basic::terminate(converged, ucell, istep, ofs); ofs.close(); // Check the results diff --git a/source/source_relax/test/ions_move_cg_test.cpp b/source/source_relax/test/ions_move_cg_test.cpp index 0b648e14c22..97eb1cda9b2 100644 --- a/source/source_relax/test/ions_move_cg_test.cpp +++ b/source/source_relax/test/ions_move_cg_test.cpp @@ -92,7 +92,6 @@ TEST_F(IonsMoveCGTest, TestStartConverged) { // setup data const int istep = 1; - Ions_Move_Basic::converged = true; UnitCell ucell; setupucell(ucell); ModuleBase::matrix force(2, 3); @@ -117,7 +116,6 @@ TEST_F(IonsMoveCGTest, TestStartConverged) std::regex pattern(R"(==> .*::.*\t[\d\.]+ GB\t\d+ s\n )"); output = std::regex_replace(output, pattern, ""); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::converged, true); EXPECT_EQ(Ions_Move_Basic::update_iter, 5); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.0); } @@ -127,7 +125,6 @@ TEST_F(IonsMoveCGTest, TestStartSd) { // setup data const int istep = 1; - Ions_Move_Basic::converged = false; Ions_Move_Basic::relax_method[0] = "cg_bfgs"; Ions_Move_CG::RELAX_CG_THR = 100.0; UnitCell ucell; @@ -150,7 +147,6 @@ TEST_F(IonsMoveCGTest, TestStartSd) std::remove("TestStartSd.log"); // mohan EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::converged, false); EXPECT_EQ(Ions_Move_Basic::update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.01); @@ -163,7 +159,6 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) { // setup data const int istep = 1; - Ions_Move_Basic::converged = false; UnitCell ucell; setupucell(ucell); ModuleBase::matrix force(2, 3); @@ -192,7 +187,6 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) std::remove("TestStartTrialGoto.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::converged, false); EXPECT_EQ(Ions_Move_Basic::update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.001); @@ -205,7 +199,6 @@ TEST_F(IonsMoveCGTest, TestStartTrial) { // setup data const int istep = 1; - Ions_Move_Basic::converged = false; UnitCell ucell; setupucell(ucell); ModuleBase::matrix force(2, 3); @@ -233,7 +226,6 @@ TEST_F(IonsMoveCGTest, TestStartTrial) std::remove("TestStartTrial.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::converged, false); EXPECT_EQ(Ions_Move_Basic::update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.01); @@ -246,7 +238,6 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) { // setup data const int istep = 1; - Ions_Move_Basic::converged = false; UnitCell ucell; setupucell(ucell); ModuleBase::matrix force(2, 3); @@ -279,7 +270,6 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) std::remove("TestStartNoTrialGotoCase1.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::converged, false); EXPECT_EQ(Ions_Move_Basic::update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.001); @@ -292,7 +282,6 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) { // setup data const int istep = 1; - Ions_Move_Basic::converged = false; UnitCell ucell; setupucell(ucell); ModuleBase::matrix force(2, 3); @@ -324,7 +313,6 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) std::remove("TestStartNoTrialGotoCase2.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::converged, false); EXPECT_EQ(Ions_Move_Basic::update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.01); @@ -337,7 +325,6 @@ TEST_F(IonsMoveCGTest, TestStartNoTrial) { // setup data const int istep = 1; - Ions_Move_Basic::converged = false; UnitCell ucell; setupucell(ucell); ModuleBase::matrix force(2, 3); @@ -370,7 +357,6 @@ TEST_F(IonsMoveCGTest, TestStartNoTrial) std::remove("TestStartNoTrial.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::converged, false); EXPECT_EQ(Ions_Move_Basic::update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.001); diff --git a/source/source_relax/test/ions_move_methods_test.cpp b/source/source_relax/test/ions_move_methods_test.cpp index 725fdaa327c..bd63dcec176 100644 --- a/source/source_relax/test/ions_move_methods_test.cpp +++ b/source/source_relax/test/ions_move_methods_test.cpp @@ -177,13 +177,7 @@ TEST_F(IonsMoveMethodsTest, CalMovementWarningQuit) std::remove("log"); } -// Test the get_converged() function -TEST_F(IonsMoveMethodsTest, GetConverged) -{ - Ions_Move_Basic::converged = true; - EXPECT_EQ(imm.get_converged(), true); -} // Test the get_ediff() function TEST_F(IonsMoveMethodsTest, GetEdiff) diff --git a/source/source_relax/test/ions_move_sd_test.cpp b/source/source_relax/test/ions_move_sd_test.cpp index 88aadbc1fc3..5ca35fec49d 100644 --- a/source/source_relax/test/ions_move_sd_test.cpp +++ b/source/source_relax/test/ions_move_sd_test.cpp @@ -68,7 +68,6 @@ TEST_F(IonsMoveSDTest, TestStartConverged) { // setup data const int istep = 1; - Ions_Move_Basic::converged = true; UnitCell ucell; ModuleBase::matrix force(2, 3); double etot = 0.0; @@ -91,7 +90,6 @@ TEST_F(IonsMoveSDTest, TestStartConverged) std::regex pattern(R"(==> .*::.*\t[\d\.]+ GB\t\d+ s\n )"); output = std::regex_replace(output, pattern, ""); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::converged, true); EXPECT_EQ(Ions_Move_Basic::update_iter, 5); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.0); EXPECT_DOUBLE_EQ(im_sd.energy_saved, 0.0); @@ -108,7 +106,6 @@ TEST_F(IonsMoveSDTest, TestStartNotConverged) { // setup data const int istep = 1; - Ions_Move_Basic::converged = true; UnitCell ucell; ModuleBase::matrix force(2, 3); force(0, 0) = 1.0; @@ -140,7 +137,6 @@ TEST_F(IonsMoveSDTest, TestStartNotConverged) std::remove("test_sd_start_not_converged.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::converged, false); EXPECT_EQ(Ions_Move_Basic::update_iter, 6); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 1.0); EXPECT_DOUBLE_EQ(im_sd.energy_saved, 0.0); diff --git a/source/source_relax/test/lattice_change_basic_test.cpp b/source/source_relax/test/lattice_change_basic_test.cpp index 61b4c56ddd2..35fd638c623 100644 --- a/source/source_relax/test/lattice_change_basic_test.cpp +++ b/source/source_relax/test/lattice_change_basic_test.cpp @@ -238,7 +238,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase1) stress(2, 2) = 9.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + bool converged = Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); ofs.close(); // Check the results @@ -248,7 +248,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase1) EXPECT_EQ(output, expected_output); EXPECT_EQ(Lattice_Change_Basic::update_iter, 0); EXPECT_NEAR(Lattice_Change_Basic::largest_grad, 1323947.0517790401, 1e-12); - EXPECT_FALSE(Lattice_Change_Basic::converged); + EXPECT_FALSE(converged); ifs.close(); std::remove("test_check_converged_case1.log"); @@ -275,7 +275,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase2) stress(2, 2) = 0.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + bool converged = Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); ofs.close(); // Check the results @@ -285,7 +285,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase2) EXPECT_EQ(output, expected_output); EXPECT_EQ(Lattice_Change_Basic::update_iter, 0); EXPECT_DOUBLE_EQ(Lattice_Change_Basic::largest_grad, 0.0); - EXPECT_TRUE(Lattice_Change_Basic::converged); + EXPECT_TRUE(converged); ifs.close(); std::remove("test_check_converged_case2.log"); @@ -312,7 +312,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase3) stress(2, 2) = 0.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + bool converged = Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); ofs.close(); // Check the results @@ -322,7 +322,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase3) EXPECT_EQ(output, expected_output); EXPECT_EQ(Lattice_Change_Basic::update_iter, 1); EXPECT_NEAR(Lattice_Change_Basic::largest_grad, 0.14710522797544887, 1e-12); - EXPECT_TRUE(Lattice_Change_Basic::converged); + EXPECT_TRUE(converged); ifs.close(); std::remove("test_check_converged_case3.log"); @@ -349,7 +349,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase4) grad[8] = 1.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + bool converged = Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); ofs.close(); // Check the results @@ -359,7 +359,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase4) EXPECT_EQ(output, expected_output); EXPECT_EQ(Lattice_Change_Basic::update_iter, 0); EXPECT_NEAR(Lattice_Change_Basic::largest_grad, 147105.22797544891, 1e-12); - EXPECT_FALSE(Lattice_Change_Basic::converged); + EXPECT_FALSE(converged); ifs.close(); std::remove("test_check_converged_case4.log"); @@ -386,7 +386,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase5) grad[8] = 0.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + bool converged = Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); ofs.close(); // Check the results @@ -396,7 +396,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase5) EXPECT_EQ(output, expected_output); EXPECT_EQ(Lattice_Change_Basic::update_iter, 0); EXPECT_DOUBLE_EQ(Lattice_Change_Basic::largest_grad, 0.0); - EXPECT_TRUE(Lattice_Change_Basic::converged); + EXPECT_TRUE(converged); ifs.close(); std::remove("test_check_converged_case5.log"); @@ -423,7 +423,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase6) grad[8] = 0.0; // Call the function under test - Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); + bool converged = Lattice_Change_Basic::check_converged(ucell, stress, grad, ofs); ofs.close(); // Check the results @@ -433,7 +433,7 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase6) EXPECT_EQ(output, expected_output); EXPECT_EQ(Lattice_Change_Basic::update_iter, 1); EXPECT_NEAR(Lattice_Change_Basic::largest_grad, 0.14710522797544887, 1e-12); - EXPECT_TRUE(Lattice_Change_Basic::converged); + EXPECT_TRUE(converged); ifs.close(); std::remove("test_check_converged_case6.log"); @@ -441,7 +441,6 @@ TEST_F(LatticeChangeBasicTest, CheckConvergedCase6) TEST_F(LatticeChangeBasicTest, TerminateConverged) { - Lattice_Change_Basic::converged = true; Lattice_Change_Basic::stress_step = 5; Lattice_Change_Basic::update_iter = 10; @@ -449,7 +448,7 @@ TEST_F(LatticeChangeBasicTest, TerminateConverged) " update iteration = 10\n"; std::ofstream ofs("test_terminate_converged.log"); - Lattice_Change_Basic::terminate(ofs); + Lattice_Change_Basic::terminate(true, ofs); ofs.close(); std::ifstream ifs("test_terminate_converged.log"); @@ -462,12 +461,10 @@ TEST_F(LatticeChangeBasicTest, TerminateConverged) TEST_F(LatticeChangeBasicTest, TerminateNotConverged) { - Lattice_Change_Basic::converged = false; - std::string expected_output = " the maximum number of steps has been reached.\n end of lattice optimization.\n"; std::ofstream ofs("test_terminate_not_converged.log"); - Lattice_Change_Basic::terminate(ofs); + Lattice_Change_Basic::terminate(false, ofs); ofs.close(); std::ifstream ifs("test_terminate_not_converged.log"); diff --git a/source/source_relax/test/lattice_change_cg_test.cpp b/source/source_relax/test/lattice_change_cg_test.cpp index b559dd556ca..ce41702614f 100644 --- a/source/source_relax/test/lattice_change_cg_test.cpp +++ b/source/source_relax/test/lattice_change_cg_test.cpp @@ -19,7 +19,6 @@ class LatticeChangeCGTest : public ::testing::Test Lattice_Change_Basic::dim = 9; Lattice_Change_Basic::stress_step = 1; Lattice_Change_Basic::update_iter = 5; - Lattice_Change_Basic::converged = true; lc_cg.allocate(); } diff --git a/source/source_relax/test/lattice_change_methods_test.cpp b/source/source_relax/test/lattice_change_methods_test.cpp index d16c338a489..8b78c7371d6 100644 --- a/source/source_relax/test/lattice_change_methods_test.cpp +++ b/source/source_relax/test/lattice_change_methods_test.cpp @@ -25,8 +25,9 @@ void Lattice_Change_CG::allocate(void) { } -void Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs) +bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs) { + return false; } // Define a fixture for the tests @@ -77,10 +78,8 @@ TEST_F(LatticeChangeMethodsTest, CalLatticeChange) // Test the get_converged function TEST_F(LatticeChangeMethodsTest, GetConverged) { - lcm.get_converged(); - - // Assert that the static variable converged is set to false - EXPECT_EQ(Lattice_Change_Basic::converged, false); + // Assert that the converged state is initially false + EXPECT_FALSE(lcm.get_converged()); } // Test the get_ediff function From 99da1dd9891152ab5115970dadec289cf8475eb6 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 15 Jun 2026 09:25:00 +0800 Subject: [PATCH 42/50] fix test --- source/source_relax/test/ions_move_cg_test.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/source_relax/test/ions_move_cg_test.cpp b/source/source_relax/test/ions_move_cg_test.cpp index 97eb1cda9b2..1fe9dd6bbe7 100644 --- a/source/source_relax/test/ions_move_cg_test.cpp +++ b/source/source_relax/test/ions_move_cg_test.cpp @@ -175,7 +175,7 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) im_cg.move0[0] = 10.0; force(0, 0) = 0.001; std::ofstream ofs("TestStartTrialGoto.log"); - im_cg.start(ucell, force, etot, istep, ofs); + im_cg.start(ucell, force, etot, istep_2, ofs); ofs.close(); // Check output @@ -214,7 +214,7 @@ TEST_F(IonsMoveCGTest, TestStartTrial) int istep_2 = 2; im_cg.move0[0] = 10.0; std::ofstream ofs("TestStartTrial.log"); - im_cg.start(ucell, force, etot, istep, ofs); + im_cg.start(ucell, force, etot, istep_2, ofs); ofs.close(); // Check output @@ -252,13 +252,13 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) std::remove("TestStartNoTrialGotoCase1_temp1.log"); int istep_2 = 2; std::ofstream ofs2("TestStartNoTrialGotoCase1_temp2.log"); - im_cg.start(ucell, force, etot, istep, ofs2); + im_cg.start(ucell, force, etot, istep_2, ofs2); ofs2.close(); std::remove("TestStartNoTrialGotoCase1_temp2.log"); im_cg.move0[0] = 1.0; force(0, 0) = 0.001; std::ofstream ofs("TestStartNoTrialGotoCase1.log"); - im_cg.start(ucell, force, etot, istep, ofs); + im_cg.start(ucell, force, etot, istep_2, ofs); ofs.close(); // Check output @@ -297,11 +297,11 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) int istep_2 = 2; im_cg.move0[0] = 10.0; std::ofstream ofs2("TestStartNoTrialGotoCase2_temp2.log"); - im_cg.start(ucell, force, etot, istep, ofs2); + im_cg.start(ucell, force, etot, istep_2, ofs2); ofs2.close(); std::remove("TestStartNoTrialGotoCase2_temp2.log"); std::ofstream ofs("TestStartNoTrialGotoCase2.log"); - im_cg.start(ucell, force, etot, istep, ofs); + im_cg.start(ucell, force, etot, istep_2, ofs); ofs.close(); // Check output @@ -341,11 +341,11 @@ TEST_F(IonsMoveCGTest, TestStartNoTrial) im_cg.move0[0] = 1.0; force(0, 0) = 0.001; std::ofstream ofs2("TestStartNoTrial_temp2.log"); - im_cg.start(ucell, force, etot, istep, ofs2); + im_cg.start(ucell, force, etot, istep_2, ofs2); ofs2.close(); std::remove("TestStartNoTrial_temp2.log"); std::ofstream ofs("TestStartNoTrial.log"); - im_cg.start(ucell, force, etot, istep, ofs); + im_cg.start(ucell, force, etot, istep_2, ofs); ofs.close(); // Check output From 236f6dd67a3963ff90fcdda7b00ee7f55b77139d Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 15 Jun 2026 11:38:45 +0800 Subject: [PATCH 43/50] remove a parameter update_iter in ions_move_basic --- source/source_relax/bfgs_basic.cpp | 42 ++++------------- source/source_relax/bfgs_basic.h | 4 +- source/source_relax/ions_move_basic.cpp | 18 +++---- source/source_relax/ions_move_basic.h | 7 +-- source/source_relax/ions_move_bfgs.cpp | 20 ++++---- source/source_relax/ions_move_bfgs.h | 6 +-- source/source_relax/ions_move_cg.cpp | 6 +-- source/source_relax/ions_move_cg.h | 2 +- source/source_relax/ions_move_methods.cpp | 10 ++-- source/source_relax/ions_move_methods.h | 5 +- source/source_relax/ions_move_sd.cpp | 8 ++-- source/source_relax/ions_move_sd.h | 2 +- source/source_relax/test/bfgs_basic_test.cpp | 15 +++--- .../test/ions_move_basic_test.cpp | 25 +++++----- .../source_relax/test/ions_move_bfgs_test.cpp | 24 +++++----- .../source_relax/test/ions_move_cg_test.cpp | 47 ++++++++++--------- .../source_relax/test/ions_move_sd_test.cpp | 11 +++-- 17 files changed, 115 insertions(+), 137 deletions(-) diff --git a/source/source_relax/bfgs_basic.cpp b/source/source_relax/bfgs_basic.cpp index 54a8c889a1b..6b31dcb5a1e 100644 --- a/source/source_relax/bfgs_basic.cpp +++ b/source/source_relax/bfgs_basic.cpp @@ -109,38 +109,12 @@ void BFGS_Basic::check_wolfe_conditions(std::ofstream& ofs) // enlarge trst radius is not good. bool wolfe2 = std::abs(dot) > -this->relax_bfgs_w2 * dot_p; - if (PARAM.inp.test_relax_method) - { - ModuleBase::GlobalFunc::OUT(ofs, "etot - etot_p", etot - etot_p); - ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w1 * dot_p", relax_bfgs_w1 * dot_p); - ModuleBase::GlobalFunc::OUT(ofs, "dot", dot); - ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w2 * dot_p", relax_bfgs_w2 * dot_p); - ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w1", relax_bfgs_w1); - ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w2", relax_bfgs_w2); - ModuleBase::GlobalFunc::OUT(ofs, "wolfe1", wolfe1); - ModuleBase::GlobalFunc::OUT(ofs, "wolfe2", wolfe2); - } - this->wolfe_flag = wolfe1 && wolfe2; - /* - for(int i=0; i 1) + else if (update_iter > 1) { this->check_wolfe_conditions(ofs); this->update_inverse_hessian(lat0, ofs); @@ -255,14 +229,14 @@ void BFGS_Basic::new_step(const double &lat0, std::ofstream& ofs) //-------------------------------------------------------------------- // the step must done after hessian is multiplied to grad. - // std::cout<<"update_iter="< 0); @@ -141,12 +140,13 @@ bool Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, if (PARAM.inp.out_level == "ie") { std::cout << " ETOT DIFF (eV) : " << Ions_Move_Basic::ediff * ModuleBase::Ry_to_eV << std::endl; - std::cout << " LARGEST GRAD (eV/Angstrom) : " << Ions_Move_Basic::largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A - << std::endl; + std::cout << " LARGEST GRAD (eV/Angstrom) : " + << Ions_Move_Basic::largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A + << std::endl; ofs << "\n Largest force is " << largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A - << " eV/Angstrom while threshold is " - << PARAM.inp.force_thr_ev << " eV/Angstrom" << std::endl; + << " eV/Angstrom while threshold is " + << PARAM.inp.force_thr_ev << " eV/Angstrom" << std::endl; } const double etot_diff = std::abs(Ions_Move_Basic::ediff); @@ -166,7 +166,7 @@ bool Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, ofs << "\n Ion relaxation is converged!" << std::endl; ofs << "\n Energy difference (Ry) = " << etot_diff << std::endl; - ++Ions_Move_Basic::update_iter; + ++update_iter; return true; } else @@ -179,14 +179,14 @@ bool Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, } } -void Ions_Move_Basic::terminate(const bool converged, const UnitCell &ucell, const int istep, std::ofstream& ofs) +void Ions_Move_Basic::terminate(const bool converged, const int update_iter, const UnitCell &ucell, const int istep, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_Basic", "terminate"); if (converged) { ofs << " end of geometry optimization" << std::endl; ModuleBase::GlobalFunc::OUT(ofs, "istep", istep); - ModuleBase::GlobalFunc::OUT(ofs, "update iteration", Ions_Move_Basic::update_iter); + ModuleBase::GlobalFunc::OUT(ofs, "update iteration", update_iter); /* ofs<<"Saving the approximate inverse hessian"<grad.data(), ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, this->grad.data(), update_iter, ofs); if (converged) { - Ions_Move_Basic::terminate(converged, ucell, istep, ofs); + Ions_Move_Basic::terminate(converged, update_iter, ucell, istep, ofs); return true; } else @@ -72,7 +72,7 @@ bool Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con // [ if run from previous saved info ] // the BFGS file is read from previous run. // and the move_p is renormalized. - this->restart_bfgs(ucell.lat0, ofs); + this->restart_bfgs(ucell.lat0, update_iter, ofs); //[ if etot>etot_p ] // interpolation @@ -80,7 +80,7 @@ bool Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con // calculate the new step -> the new move using hessian // matrix, and set the new trust radius. // [compute the move at last] - this->bfgs_routine(ucell.lat0, istep, ofs); + this->bfgs_routine(ucell.lat0, istep, update_iter, ofs); // get prepared for the next try. // even if the energy is higher, we save the information. @@ -91,7 +91,7 @@ bool Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con } } -void Ions_Move_BFGS::restart_bfgs(const double& lat0, std::ofstream& ofs) +void Ions_Move_BFGS::restart_bfgs(const double& lat0, int& update_iter, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_BFGS", "restart_bfgs"); @@ -134,7 +134,7 @@ void Ions_Move_BFGS::restart_bfgs(const double& lat0, std::ofstream& ofs) std::fill(grad_p.begin(), grad_p.end(), 0.0); std::fill(move_p.begin(), move_p.end(), 0.0); - Ions_Move_Basic::update_iter = 0; + update_iter = 0; // set the trust radius old as the initial trust radius. trust_radius_old = relax_bfgs_init; @@ -167,7 +167,7 @@ void Ions_Move_BFGS::restart_bfgs(const double& lat0, std::ofstream& ofs) return; } -void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, std::ofstream& ofs) +void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, int& update_iter, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_BFGS", "bfgs_routine"); using namespace Ions_Move_Basic; @@ -292,7 +292,7 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, std::ofst } else if (etot <= etot_p) { - this->new_step(lat0, ofs); + this->new_step(lat0, update_iter, ofs); } if (PARAM.inp.out_level == "ie") @@ -301,7 +301,7 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, std::ofst } ModuleBase::GlobalFunc::OUT(ofs, "istep", istep); - ModuleBase::GlobalFunc::OUT(ofs, "update iteration", Ions_Move_Basic::update_iter); + ModuleBase::GlobalFunc::OUT(ofs, "update iteration", update_iter); // combine the direction and move length now double norm = dot_func(this->move.data(), this->move.data(), dim); diff --git a/source/source_relax/ions_move_bfgs.h b/source/source_relax/ions_move_bfgs.h index 74d72e5cf69..863db2e2533 100644 --- a/source/source_relax/ions_move_bfgs.h +++ b/source/source_relax/ions_move_bfgs.h @@ -13,12 +13,12 @@ class Ions_Move_BFGS : public BFGS_Basic ~Ions_Move_BFGS(); void allocate(void); - bool start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, std::ofstream& ofs); + bool start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, int& update_iter, std::ofstream& ofs); private: bool init_done; - void bfgs_routine(const double& lat0, const int istep, std::ofstream& ofs); - void restart_bfgs(const double& lat0, std::ofstream& ofs); + void bfgs_routine(const double& lat0, const int istep, int& update_iter, std::ofstream& ofs); + void restart_bfgs(const double& lat0, int& update_iter, std::ofstream& ofs); bool first_step=true; // If it is the first step of the relaxation. The pos is only generated from ucell in the first step, and in the following steps, the pos is generated from the previous step. }; diff --git a/source/source_relax/ions_move_cg.cpp b/source/source_relax/ions_move_cg.cpp index 6e87fc6b885..3ed81874683 100644 --- a/source/source_relax/ions_move_cg.cpp +++ b/source/source_relax/ions_move_cg.cpp @@ -23,7 +23,7 @@ void Ions_Move_CG::allocate(const int dim) this->e0 = 0.0; } -bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, const int istep, std::ofstream& ofs) +bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, const int istep, int& update_iter, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_CG", "start"); assert(Ions_Move_Basic::dim > 0); @@ -77,11 +77,11 @@ bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const bool converged = false; if (flag == 0) { - converged = Ions_Move_Basic::check_converged(ucell, grad.data(), ofs); + converged = Ions_Move_Basic::check_converged(ucell, grad.data(), update_iter, ofs); } if (converged) { - Ions_Move_Basic::terminate(converged, ucell, istep, ofs); + Ions_Move_Basic::terminate(converged, update_iter, ucell, istep, ofs); return true; } diff --git a/source/source_relax/ions_move_cg.h b/source/source_relax/ions_move_cg.h index 7b25e5dd575..063a5442647 100644 --- a/source/source_relax/ions_move_cg.h +++ b/source/source_relax/ions_move_cg.h @@ -15,7 +15,7 @@ class Ions_Move_CG : public CG_Base ~Ions_Move_CG() = default; void allocate(const int dim); - bool start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, const int istep, std::ofstream& ofs); + bool start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, const int istep, int& update_iter, std::ofstream& ofs); static double RELAX_CG_THR; int sd_step = 0; diff --git a/source/source_relax/ions_move_methods.cpp b/source/source_relax/ions_move_methods.cpp index 6b1bf95582b..c1df2be53b2 100644 --- a/source/source_relax/ions_move_methods.cpp +++ b/source/source_relax/ions_move_methods.cpp @@ -66,19 +66,15 @@ void Ions_Move_Methods::cal_movement(const int &istep, // move_ions // output tau // check all symmery - converged_ = bfgs.start(ucell, f, etot, force_step, ofs); - } - else if (Ions_Move_Basic::relax_method[0] == "sd") - { - converged_ = sd.start(ucell, f, etot, force_step, ofs); + converged_ = bfgs.start(ucell, f, etot, force_step, update_iter_, ofs); } else if (Ions_Move_Basic::relax_method[0] == "cg") { - converged_ = cg.start(ucell, f, etot, force_step, ofs); + converged_ = cg.start(ucell, f, etot, force_step, update_iter_, ofs); } else if (Ions_Move_Basic::relax_method[0] == "cg_bfgs") { - converged_ = cg.start(ucell, f, etot, force_step, ofs); // added by pengfei 13-8-10 + converged_ = cg.start(ucell, f, etot, force_step, update_iter_, ofs); // added by pengfei 13-8-10 } else if(Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] == "1") { diff --git a/source/source_relax/ions_move_methods.h b/source/source_relax/ions_move_methods.h index a63d0e29466..b5bf206b7c2 100644 --- a/source/source_relax/ions_move_methods.h +++ b/source/source_relax/ions_move_methods.h @@ -42,9 +42,9 @@ class Ions_Move_Methods { return Ions_Move_Basic::trust_radius; } - double get_update_iter() const + int get_update_iter() const { - return Ions_Move_Basic::update_iter; + return update_iter_; } private: @@ -54,5 +54,6 @@ class Ions_Move_Methods Ions_Move_BFGS2 bfgs_trad; Ions_Move_LBFGS lbfgs; bool converged_ = false; + int update_iter_ = 0; }; #endif diff --git a/source/source_relax/ions_move_sd.cpp b/source/source_relax/ions_move_sd.cpp index ed7af225a76..ca87a9e45e3 100644 --- a/source/source_relax/ions_move_sd.cpp +++ b/source/source_relax/ions_move_sd.cpp @@ -20,7 +20,7 @@ void Ions_Move_SD::allocate() pos_saved.resize(dim, 0.0); } -bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot_in, const int istep, std::ofstream& ofs) +bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot_in, const int istep, int& update_iter, std::ofstream& ofs) { ModuleBase::TITLE("Ions_Move_SD", "start"); @@ -61,10 +61,10 @@ bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const } } - bool converged = Ions_Move_Basic::check_converged(ucell, grad.data(), ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad.data(), update_iter, ofs); if (converged) { - Ions_Move_Basic::terminate(converged, ucell, istep, ofs); + Ions_Move_Basic::terminate(converged, update_iter, ucell, istep, ofs); return true; } else @@ -75,7 +75,7 @@ bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const move[i] = -grad_saved[i] * trust_radius; } move_atoms(ucell, move.data(), pos_saved.data(), ofs); - Ions_Move_Basic::update_iter++; + update_iter++; return false; } } diff --git a/source/source_relax/ions_move_sd.h b/source/source_relax/ions_move_sd.h index ad3a48b0e30..d59568efb81 100644 --- a/source/source_relax/ions_move_sd.h +++ b/source/source_relax/ions_move_sd.h @@ -14,7 +14,7 @@ class Ions_Move_SD ~Ions_Move_SD() = default; void allocate(void); - bool start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot, const int istep, std::ofstream& ofs); + bool start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot, const int istep, int& update_iter, std::ofstream& ofs); private: double energy_saved; diff --git a/source/source_relax/test/bfgs_basic_test.cpp b/source/source_relax/test/bfgs_basic_test.cpp index 184632a8976..f69f76a036e 100644 --- a/source/source_relax/test/bfgs_basic_test.cpp +++ b/source/source_relax/test/bfgs_basic_test.cpp @@ -188,7 +188,7 @@ TEST_F(BFGSBasicTest, SaveBfgs) TEST_F(BFGSBasicTest, NewStepCase1) { Ions_Move_Basic::dim = 2; - Ions_Move_Basic::update_iter = 0; + int update_iter = 0; Ions_Move_Basic::largest_grad = 0.0; Ions_Move_Basic::relax_bfgs_init = 0.3; Ions_Move_Basic::best_xxx = -0.4; @@ -203,9 +203,9 @@ TEST_F(BFGSBasicTest, NewStepCase1) double lat0 = 1.0; std::ofstream ofs("test_log.log"); - bfgs.new_step(lat0, ofs); + bfgs.new_step(lat0, update_iter, ofs); - EXPECT_EQ(Ions_Move_Basic::update_iter, 1); + EXPECT_EQ(update_iter, 1); EXPECT_EQ(bfgs.tr_min_hit, false); EXPECT_DOUBLE_EQ(Ions_Move_Basic::relax_bfgs_init, 0.2); EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, 0.4); @@ -222,7 +222,7 @@ TEST_F(BFGSBasicTest, NewStepCase1) TEST_F(BFGSBasicTest, NewStepCase2) { Ions_Move_Basic::dim = 2; - Ions_Move_Basic::update_iter = 2; + int update_iter = 2; Ions_Move_Basic::largest_grad = 0.0; Ions_Move_Basic::relax_bfgs_init = 0.3; Ions_Move_Basic::best_xxx = -0.4; @@ -237,9 +237,9 @@ TEST_F(BFGSBasicTest, NewStepCase2) double lat0 = 1.0; std::ofstream ofs("test_log.log"); - bfgs.new_step(lat0, ofs); + bfgs.new_step(lat0, update_iter, ofs); - EXPECT_EQ(Ions_Move_Basic::update_iter, 3); + EXPECT_EQ(update_iter, 3); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, -1.0); EXPECT_DOUBLE_EQ(bfgs.move[0], -1.0); EXPECT_DOUBLE_EQ(bfgs.move[1], -2.0); @@ -253,13 +253,14 @@ TEST_F(BFGSBasicTest, NewStepCase2) TEST_F(BFGSBasicTest, NewStepWarningQuit) { Ions_Move_Basic::dim = 2; + int update_iter = 0; bfgs.bfgs_ndim = 2; bfgs.allocate_basic(); double lat0 = 1.0; std::ofstream ofs("test_log.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.new_step(lat0, ofs), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.new_step(lat0, update_iter, ofs), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("bfgs_ndim > 1 not implemented yet")); } diff --git a/source/source_relax/test/ions_move_basic_test.cpp b/source/source_relax/test/ions_move_basic_test.cpp index 8e38958c46d..0bc70327ba0 100644 --- a/source/source_relax/test/ions_move_basic_test.cpp +++ b/source/source_relax/test/ions_move_basic_test.cpp @@ -102,7 +102,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase1) { // Initialize data Ions_Move_Basic::dim = 6; - Ions_Move_Basic::update_iter = 1; + int update_iter = 1; PARAM.input.test_relax_method = 1; PARAM.input.out_level = "ie"; for (int i = 0; i < Ions_Move_Basic::dim; ++i) @@ -113,7 +113,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase1) // Call the function being tested std::ofstream ofs("test_check_converged_case1.log"); testing::internal::CaptureStdout(); - bool converged = Ions_Move_Basic::check_converged(ucell, grad, ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad, update_iter, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -132,7 +132,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase1) EXPECT_THAT(ofs_output , ::testing::HasSubstr(expected_ofs)); EXPECT_EQ(expected_std, std_outout); - EXPECT_EQ(Ions_Move_Basic::update_iter, 1); + EXPECT_EQ(update_iter, 1); EXPECT_EQ(converged, true); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.0); } @@ -142,7 +142,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase2) { // Initialize data Ions_Move_Basic::dim = 6; - Ions_Move_Basic::update_iter = 1; + int update_iter = 1; Ions_Move_Basic::ediff = 0.0; PARAM.input.test_relax_method = 1; PARAM.input.out_level = "ie"; @@ -152,7 +152,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase2) // Call the function being tested std::ofstream ofs("test_check_converged_case2.log"); testing::internal::CaptureStdout(); - bool converged = Ions_Move_Basic::check_converged(ucell, grad, ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad, update_iter, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -171,7 +171,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase2) EXPECT_THAT(ofs_output , ::testing::HasSubstr(expected_ofs)); EXPECT_EQ(expected_std, std_outout); - EXPECT_EQ(Ions_Move_Basic::update_iter, 2); + EXPECT_EQ(update_iter, 2); EXPECT_EQ(converged, true); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.1); } @@ -181,7 +181,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase3) { // Initialize data Ions_Move_Basic::dim = 6; - Ions_Move_Basic::update_iter = 1; + int update_iter = 1; Ions_Move_Basic::ediff = 1.0; PARAM.input.test_relax_method = 1; PARAM.input.out_level = "ie"; @@ -191,7 +191,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase3) // Call the function being tested std::ofstream ofs("test_check_converged_case3.log"); testing::internal::CaptureStdout(); - bool converged = Ions_Move_Basic::check_converged(ucell, grad, ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad, update_iter, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -210,7 +210,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase3) EXPECT_THAT(ofs_output , ::testing::HasSubstr(expected_ofs)); EXPECT_EQ(expected_std, std_outout); - EXPECT_EQ(Ions_Move_Basic::update_iter, 1); + EXPECT_EQ(update_iter, 1); EXPECT_EQ(converged, false); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.1); } @@ -221,11 +221,11 @@ TEST_F(IonsMoveBasicTest, TerminateConverged) // Initialize data const bool converged = true; const int istep = 2; - Ions_Move_Basic::update_iter = 5; + const int update_iter = 5; // Call the function being tested std::ofstream ofs("test_terminate_converged.log"); - Ions_Move_Basic::terminate(converged, ucell, istep, ofs); + Ions_Move_Basic::terminate(converged, update_iter, ucell, istep, ofs); ofs.close(); // Check the results @@ -246,10 +246,11 @@ TEST_F(IonsMoveBasicTest, TerminateNotConverged) // Initialize data const bool converged = false; const int istep = 10; + const int update_iter = 0; // Call the function being tested std::ofstream ofs("test_terminate_not_converged.log"); - Ions_Move_Basic::terminate(converged, ucell, istep, ofs); + Ions_Move_Basic::terminate(converged, update_iter, ucell, istep, ofs); ofs.close(); // Check the results diff --git a/source/source_relax/test/ions_move_bfgs_test.cpp b/source/source_relax/test/ions_move_bfgs_test.cpp index 79b27b280a8..6efaa1402e9 100644 --- a/source/source_relax/test/ions_move_bfgs_test.cpp +++ b/source/source_relax/test/ions_move_bfgs_test.cpp @@ -18,11 +18,13 @@ class IonsMoveBFGSTest : public ::testing::Test { protected: Ions_Move_BFGS bfgs; + int update_iter; virtual void SetUp() { // Initialize variables before each test Ions_Move_Basic::dim = 6; + update_iter = 0; } virtual void TearDown() @@ -75,7 +77,7 @@ TEST_F(IonsMoveBFGSTest, StartCase1) // Call the function being tested bfgs.allocate(); std::ofstream ofs("test_start_case1.log"); - bfgs.start(ucell, force, energy_in, istep, ofs); + bfgs.start(ucell, force, energy_in, istep, update_iter, ofs); ofs.close(); // Check the results @@ -123,7 +125,7 @@ TEST_F(IonsMoveBFGSTest, StartCase2) // Call the function being tested bfgs.allocate(); std::ofstream ofs("test_start_case2.log"); - bfgs.start(ucell, force, energy_in, istep, ofs); + bfgs.start(ucell, force, energy_in, istep, update_iter, ofs); ofs.close(); // Check the results @@ -156,7 +158,7 @@ TEST_F(IonsMoveBFGSTest, RestartBfgsCase1) // Call the function being tested std::ofstream ofs("test_restart_bfgs_case1.log"); - bfgs.restart_bfgs(lat0, ofs); + bfgs.restart_bfgs(lat0, update_iter, ofs); ofs.close(); // Check the results @@ -194,12 +196,12 @@ TEST_F(IonsMoveBFGSTest, RestartBfgsCase2) // Call the function being tested std::ofstream ofs("test_restart_bfgs_case2.log"); - bfgs.restart_bfgs(lat0, ofs); + bfgs.restart_bfgs(lat0, update_iter, ofs); ofs.close(); std::remove("test_restart_bfgs_case2.log"); // Check the results - EXPECT_DOUBLE_EQ(Ions_Move_Basic::update_iter, 0.0); + EXPECT_DOUBLE_EQ(update_iter, 0.0); EXPECT_DOUBLE_EQ(bfgs.tr_min_hit, false); for (int i = 0; i < Ions_Move_Basic::dim; ++i) { @@ -244,7 +246,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase1) // Call the function being tested std::ofstream ofs("test_bfgs_routine_case1.log"); testing::internal::CaptureStdout(); - bfgs.bfgs_routine(lat0, istep, ofs); + bfgs.bfgs_routine(lat0, istep, update_iter, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -310,7 +312,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase2) // Call the function being tested std::ofstream ofs("test_bfgs_routine_case2.log"); testing::internal::CaptureStdout(); - bfgs.bfgs_routine(lat0, istep, ofs); + bfgs.bfgs_routine(lat0, istep, update_iter, ofs); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -354,7 +356,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase3) const int istep = 1; Ions_Move_Basic::etot = 0.9; Ions_Move_Basic::etot_p = 1.0; - Ions_Move_Basic::update_iter = 0; + update_iter = 0; Ions_Move_Basic::largest_grad = 0.0; Ions_Move_Basic::relax_bfgs_init = 0.3; Ions_Move_Basic::best_xxx = -0.4; @@ -370,7 +372,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase3) // Call the function being tested std::ofstream ofs("test_bfgs_routine_case3.log"); - bfgs.bfgs_routine(lat0, istep, ofs); + bfgs.bfgs_routine(lat0, istep, update_iter, ofs); ofs.close(); // Check the results @@ -429,7 +431,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit1) // Check the results std::ofstream ofs("test_bfgs_routine_warning_quit1.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.bfgs_routine(lat0, istep, ofs), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.bfgs_routine(lat0, istep, update_iter, ofs), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); ofs.close(); std::remove("test_bfgs_routine_warning_quit1.log"); @@ -454,7 +456,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit2) // Check the results std::ofstream ofs("test_bfgs_routine_warning_quit2.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.bfgs_routine(lat0, istep, ofs), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.bfgs_routine(lat0, istep, update_iter, ofs), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); ofs.close(); std::remove("test_bfgs_routine_warning_quit2.log"); diff --git a/source/source_relax/test/ions_move_cg_test.cpp b/source/source_relax/test/ions_move_cg_test.cpp index 1fe9dd6bbe7..9fd38da2420 100644 --- a/source/source_relax/test/ions_move_cg_test.cpp +++ b/source/source_relax/test/ions_move_cg_test.cpp @@ -19,7 +19,7 @@ class IonsMoveCGTest : public ::testing::Test { // Initialize variables before each test Ions_Move_Basic::dim = 6; - Ions_Move_Basic::update_iter = 5; + update_iter = 5; im_cg.allocate(Ions_Move_Basic::dim); PARAM.input.force_thr = 0.001; @@ -52,6 +52,7 @@ class IonsMoveCGTest : public ::testing::Test ucell.lat.GT.Zero(); } Ions_Move_CG im_cg; + int update_iter; }; // Test whether the allocate() function can correctly allocate memory space @@ -99,7 +100,7 @@ TEST_F(IonsMoveCGTest, TestStartConverged) // call function std::ofstream ofs("TestStartConverged.log"); - im_cg.start(ucell, force, etot, istep, ofs); + im_cg.start(ucell, force, etot, istep, update_iter, ofs); ofs.close(); // Check output @@ -116,7 +117,7 @@ TEST_F(IonsMoveCGTest, TestStartConverged) std::regex pattern(R"(==> .*::.*\t[\d\.]+ GB\t\d+ s\n )"); output = std::regex_replace(output, pattern, ""); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::update_iter, 5); + EXPECT_EQ(update_iter, 5); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.0); } @@ -135,7 +136,7 @@ TEST_F(IonsMoveCGTest, TestStartSd) // call function std::ofstream ofs("TestStartSd.log"); - im_cg.start(ucell, force, etot, istep, ofs); + im_cg.start(ucell, force, etot, istep, update_iter, ofs); ofs.close(); // Check output @@ -147,7 +148,7 @@ TEST_F(IonsMoveCGTest, TestStartSd) std::remove("TestStartSd.log"); // mohan EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::update_iter, 5); + EXPECT_EQ(update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.01); EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); @@ -168,14 +169,14 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartTrialGoto_temp1.log"); - im_cg.start(ucell, force, etot, istep, ofs1); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1); ofs1.close(); std::remove("TestStartTrialGoto_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 10.0; force(0, 0) = 0.001; std::ofstream ofs("TestStartTrialGoto.log"); - im_cg.start(ucell, force, etot, istep_2, ofs); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs); ofs.close(); // Check output @@ -187,7 +188,7 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) std::remove("TestStartTrialGoto.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::update_iter, 5); + EXPECT_EQ(update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.001); EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); @@ -208,13 +209,13 @@ TEST_F(IonsMoveCGTest, TestStartTrial) // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartTrial_temp1.log"); - im_cg.start(ucell, force, etot, istep, ofs1); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1); ofs1.close(); std::remove("TestStartTrial_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 10.0; std::ofstream ofs("TestStartTrial.log"); - im_cg.start(ucell, force, etot, istep_2, ofs); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs); ofs.close(); // Check output @@ -226,7 +227,7 @@ TEST_F(IonsMoveCGTest, TestStartTrial) std::remove("TestStartTrial.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::update_iter, 5); + EXPECT_EQ(update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.01); EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); @@ -247,18 +248,18 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrialGotoCase1_temp1.log"); - im_cg.start(ucell, force, etot, istep, ofs1); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1); ofs1.close(); std::remove("TestStartNoTrialGotoCase1_temp1.log"); int istep_2 = 2; std::ofstream ofs2("TestStartNoTrialGotoCase1_temp2.log"); - im_cg.start(ucell, force, etot, istep_2, ofs2); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2); ofs2.close(); std::remove("TestStartNoTrialGotoCase1_temp2.log"); im_cg.move0[0] = 1.0; force(0, 0) = 0.001; std::ofstream ofs("TestStartNoTrialGotoCase1.log"); - im_cg.start(ucell, force, etot, istep_2, ofs); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs); ofs.close(); // Check output @@ -270,7 +271,7 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) std::remove("TestStartNoTrialGotoCase1.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::update_iter, 5); + EXPECT_EQ(update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.001); EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); @@ -291,17 +292,17 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrialGotoCase2_temp1.log"); - im_cg.start(ucell, force, etot, istep, ofs1); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1); ofs1.close(); std::remove("TestStartNoTrialGotoCase2_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 10.0; std::ofstream ofs2("TestStartNoTrialGotoCase2_temp2.log"); - im_cg.start(ucell, force, etot, istep_2, ofs2); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2); ofs2.close(); std::remove("TestStartNoTrialGotoCase2_temp2.log"); std::ofstream ofs("TestStartNoTrialGotoCase2.log"); - im_cg.start(ucell, force, etot, istep_2, ofs); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs); ofs.close(); // Check output @@ -313,7 +314,7 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) std::remove("TestStartNoTrialGotoCase2.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::update_iter, 5); + EXPECT_EQ(update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.01); EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); @@ -334,18 +335,18 @@ TEST_F(IonsMoveCGTest, TestStartNoTrial) // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrial_temp1.log"); - im_cg.start(ucell, force, etot, istep, ofs1); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1); ofs1.close(); std::remove("TestStartNoTrial_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 1.0; force(0, 0) = 0.001; std::ofstream ofs2("TestStartNoTrial_temp2.log"); - im_cg.start(ucell, force, etot, istep_2, ofs2); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2); ofs2.close(); std::remove("TestStartNoTrial_temp2.log"); std::ofstream ofs("TestStartNoTrial.log"); - im_cg.start(ucell, force, etot, istep_2, ofs); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs); ofs.close(); // Check output @@ -357,7 +358,7 @@ TEST_F(IonsMoveCGTest, TestStartNoTrial) std::remove("TestStartNoTrial.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::update_iter, 5); + EXPECT_EQ(update_iter, 5); EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.001); EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); diff --git a/source/source_relax/test/ions_move_sd_test.cpp b/source/source_relax/test/ions_move_sd_test.cpp index 5ca35fec49d..de0ad019c93 100644 --- a/source/source_relax/test/ions_move_sd_test.cpp +++ b/source/source_relax/test/ions_move_sd_test.cpp @@ -19,7 +19,7 @@ class IonsMoveSDTest : public ::testing::Test { // Initialize variables before each test Ions_Move_Basic::dim = 6; - Ions_Move_Basic::update_iter = 5; + update_iter = 5; im_sd.allocate(); PARAM.input.force_thr = 0.001; } @@ -30,6 +30,7 @@ class IonsMoveSDTest : public ::testing::Test } Ions_Move_SD im_sd; + int update_iter; }; // Test whether the allocate() function can correctly allocate memory space @@ -74,7 +75,7 @@ TEST_F(IonsMoveSDTest, TestStartConverged) // call function std::ofstream ofs("test_sd_start_converged.log"); - im_sd.start(ucell, force, etot, istep, ofs); + im_sd.start(ucell, force, etot, istep, update_iter, ofs); ofs.close(); // Check output @@ -90,7 +91,7 @@ TEST_F(IonsMoveSDTest, TestStartConverged) std::regex pattern(R"(==> .*::.*\t[\d\.]+ GB\t\d+ s\n )"); output = std::regex_replace(output, pattern, ""); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::update_iter, 5); + EXPECT_EQ(update_iter, 5); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.0); EXPECT_DOUBLE_EQ(im_sd.energy_saved, 0.0); EXPECT_DOUBLE_EQ(im_sd.pos_saved[0], 0.0); @@ -125,7 +126,7 @@ TEST_F(IonsMoveSDTest, TestStartNotConverged) // call function std::ofstream ofs("test_sd_start_not_converged.log"); - im_sd.start(ucell, force, etot, istep, ofs); + im_sd.start(ucell, force, etot, istep, update_iter, ofs); ofs.close(); // Check output @@ -137,7 +138,7 @@ TEST_F(IonsMoveSDTest, TestStartNotConverged) std::remove("test_sd_start_not_converged.log"); EXPECT_THAT(output, testing::HasSubstr(expected_output)); - EXPECT_EQ(Ions_Move_Basic::update_iter, 6); + EXPECT_EQ(update_iter, 6); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 1.0); EXPECT_DOUBLE_EQ(im_sd.energy_saved, 0.0); EXPECT_DOUBLE_EQ(im_sd.pos_saved[0], -1.0); From 3958fbc0ccfcf528a68addc8437a3450a392b92d Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 15 Jun 2026 12:31:36 +0800 Subject: [PATCH 44/50] remove some variables abot etot and etot_p --- source/source_relax/bfgs_basic.cpp | 38 ++++--- source/source_relax/bfgs_basic.h | 6 +- source/source_relax/ions_move_basic.cpp | 68 +++++------- source/source_relax/ions_move_basic.h | 12 +-- source/source_relax/ions_move_bfgs.cpp | 100 +++--------------- source/source_relax/ions_move_bfgs.h | 5 +- source/source_relax/ions_move_cg.cpp | 6 +- source/source_relax/ions_move_cg.h | 2 +- source/source_relax/ions_move_methods.cpp | 13 +-- source/source_relax/ions_move_methods.h | 5 +- source/source_relax/ions_move_sd.cpp | 19 ++-- source/source_relax/ions_move_sd.h | 4 +- source/source_relax/test/bfgs_basic_test.cpp | 28 ++--- .../test/ions_move_basic_test.cpp | 69 ++++++------ .../source_relax/test/ions_move_bfgs_test.cpp | 37 +++---- .../source_relax/test/ions_move_cg_test.cpp | 37 ++++--- .../test/ions_move_methods_test.cpp | 5 +- .../source_relax/test/ions_move_sd_test.cpp | 20 ++-- 18 files changed, 202 insertions(+), 272 deletions(-) diff --git a/source/source_relax/bfgs_basic.cpp b/source/source_relax/bfgs_basic.cpp index 6b31dcb5a1e..e3e0db0c522 100644 --- a/source/source_relax/bfgs_basic.cpp +++ b/source/source_relax/bfgs_basic.cpp @@ -96,22 +96,31 @@ void BFGS_Basic::update_inverse_hessian(const double &lat0, std::ofstream& ofs) return; } -void BFGS_Basic::check_wolfe_conditions(std::ofstream& ofs) +void BFGS_Basic::check_wolfe_conditions(std::ofstream& ofs, std::vector& etot_info) { double dot_p = dot_func(grad_p.data(), move_p.data(), dim); double dot = dot_func(grad.data(), move_p.data(), dim); - // if the total energy falls rapidly, enlarge the trust radius. - bool wolfe1 = (etot - etot_p) < this->relax_bfgs_w1 * dot_p; + // etot_info[0] = etot (current total energy) + // etot_info[1] = etot_p (previous total energy) + // ediff = etot_info[0] - etot_info[1] (computed on demand) + const double ediff = etot_info[0] - etot_info[1]; + + bool wolfe1 = ediff < this->relax_bfgs_w1 * dot_p; - // if the force is still very large, enlarge the trust radius, - // otherwise the dot should be very small, in this case, - // enlarge trst radius is not good. bool wolfe2 = std::abs(dot) > -this->relax_bfgs_w2 * dot_p; this->wolfe_flag = wolfe1 && wolfe2; - ModuleBase::GlobalFunc::OUT(ofs, "etot - etot_p", etot - etot_p); + ModuleBase::GlobalFunc::OUT(ofs, "etot - etot_p", ediff); + ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w1 * dot_p", relax_bfgs_w1 * dot_p); + ModuleBase::GlobalFunc::OUT(ofs, "dot", dot); + ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w2 * dot_p", relax_bfgs_w2 * dot_p); + ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w1", relax_bfgs_w1); + ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w2", relax_bfgs_w2); + ModuleBase::GlobalFunc::OUT(ofs, "wolfe1", wolfe1); + ModuleBase::GlobalFunc::OUT(ofs, "wolfe2", wolfe2); + ModuleBase::GlobalFunc::OUT(ofs, "etot - etot_p", ediff); ModuleBase::GlobalFunc::OUT(ofs, "relax_bfgs_w1 * dot_p", relax_bfgs_w1 * dot_p); ModuleBase::GlobalFunc::OUT(ofs, "wolfe1", wolfe1); ModuleBase::GlobalFunc::OUT(ofs, "wolfe2", wolfe2); @@ -149,7 +158,7 @@ void BFGS_Basic::save_bfgs(void) // a new bfgs step is done // we have already done well in the previous direction // we should get a new direction in this case -void BFGS_Basic::new_step(const double &lat0, int& update_iter, std::ofstream& ofs) +void BFGS_Basic::new_step(const double &lat0, int& update_iter, std::ofstream& ofs, std::vector& etot_info) { ModuleBase::TITLE("BFGS_Basic", "new_step"); @@ -177,7 +186,7 @@ void BFGS_Basic::new_step(const double &lat0, int& update_iter, std::ofstream& o } else if (update_iter > 1) { - this->check_wolfe_conditions(ofs); + this->check_wolfe_conditions(ofs, etot_info); this->update_inverse_hessian(lat0, ofs); } @@ -239,7 +248,7 @@ void BFGS_Basic::new_step(const double &lat0, int& update_iter, std::ofstream& o else if (update_iter > 1) { trust_radius = trust_radius_old; - this->compute_trust_radius(ofs); + this->compute_trust_radius(ofs, etot_info); } // std::cout<<"trust_radius ="<<" "<& etot_info) { ModuleBase::TITLE("BFGS_Basic", "compute_trust_radius"); + // etot_info[0] = etot (current total energy) + // etot_info[1] = etot_p (previous total energy) + // ediff = etot_info[0] - etot_info[1] (computed on demand) + const double ediff = etot_info[0] - etot_info[1]; + // (1) judge 1 double dot = dot_func(grad_p.data(), move_p.data(), dim); - bool ltest = (etot - etot_p) < this->relax_bfgs_w1 * dot; + bool ltest = ediff < this->relax_bfgs_w1 * dot; // (2) judge 2 // calculate the norm of move, which diff --git a/source/source_relax/bfgs_basic.h b/source/source_relax/bfgs_basic.h index 30227985326..ce42c52ee19 100644 --- a/source/source_relax/bfgs_basic.h +++ b/source/source_relax/bfgs_basic.h @@ -25,7 +25,7 @@ class BFGS_Basic protected: void allocate_basic(void); - void new_step(const double& lat0, int& update_iter, std::ofstream& ofs); + void new_step(const double& lat0, int& update_iter, std::ofstream& ofs, std::vector& etot_info); void reset_hessian(void); void save_bfgs(void); @@ -56,8 +56,8 @@ class BFGS_Basic int bfgs_ndim; void update_inverse_hessian(const double& lat0, std::ofstream& ofs); - void check_wolfe_conditions(std::ofstream& ofs); - void compute_trust_radius(std::ofstream& ofs); + void check_wolfe_conditions(std::ofstream& ofs, std::vector& etot_info); + void compute_trust_radius(std::ofstream& ofs, std::vector& etot_info); }; #endif diff --git a/source/source_relax/ions_move_basic.cpp b/source/source_relax/ions_move_basic.cpp index 8ff495fa6fb..40dd89683d2 100644 --- a/source/source_relax/ions_move_basic.cpp +++ b/source/source_relax/ions_move_basic.cpp @@ -110,14 +110,15 @@ void Ions_Move_Basic::move_atoms(UnitCell &ucell, double *move, double *pos, std return; } -bool Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, int& update_iter, std::ofstream& ofs) +bool Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, int& update_iter, std::ofstream& ofs, std::vector& etot_info) { ModuleBase::TITLE("Ions_Move_Basic", "check_converged"); assert(dim > 0); - //------------------------------------------------ - // check the gradient value - //------------------------------------------------ + // etot_info[0] = etot (current total energy) + // etot_info[1] = etot_p (previous total energy) + // ediff = etot_info[0] - etot_info[1] (computed on demand) + Ions_Move_Basic::largest_grad = 0.0; for (int i = 0; i < dim; i++) { @@ -126,20 +127,21 @@ bool Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, Ions_Move_Basic::largest_grad = std::abs(grad[i]); } } - // mohan add 2010-08-06 Ions_Move_Basic::largest_grad /= ucell.lat0; if (PARAM.inp.test_relax_method) { - ModuleBase::GlobalFunc::OUT(ofs, "old total energy (ry)", etot_p); - ModuleBase::GlobalFunc::OUT(ofs, "new total energy (ry)", etot); - ModuleBase::GlobalFunc::OUT(ofs, "energy difference (ry)", Ions_Move_Basic::ediff); + ModuleBase::GlobalFunc::OUT(ofs, "old total energy (ry)", etot_info[1]); + ModuleBase::GlobalFunc::OUT(ofs, "new total energy (ry)", etot_info[0]); + const double ediff = etot_info[0] - etot_info[1]; + ModuleBase::GlobalFunc::OUT(ofs, "energy difference (ry)", ediff); ModuleBase::GlobalFunc::OUT(ofs, "largest gradient (ry/bohr)", Ions_Move_Basic::largest_grad); } if (PARAM.inp.out_level == "ie") { - std::cout << " ETOT DIFF (eV) : " << Ions_Move_Basic::ediff * ModuleBase::Ry_to_eV << std::endl; + const double ediff = etot_info[0] - etot_info[1]; + std::cout << " ETOT DIFF (eV) : " << ediff * ModuleBase::Ry_to_eV << std::endl; std::cout << " LARGEST GRAD (eV/Angstrom) : " << Ions_Move_Basic::largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A << std::endl; @@ -149,10 +151,9 @@ bool Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, << PARAM.inp.force_thr_ev << " eV/Angstrom" << std::endl; } - const double etot_diff = std::abs(Ions_Move_Basic::ediff); + const double etot_diff = std::abs(etot_info[0] - etot_info[1]); - // need to update, mohan 2010-07-10 - const double etot_thr = 1.0e-3; // Rydeberg. + const double etot_thr = 1.0e-3; if (Ions_Move_Basic::largest_grad == 0.0) { @@ -160,7 +161,6 @@ bool Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, ofs << " it may converged, otherwise no movement of atom is allowed." << std::endl; return true; } - // mohan update 2011-04-21 else if (etot_diff < etot_thr && Ions_Move_Basic::largest_grad < PARAM.inp.force_thr ) { ofs << "\n Ion relaxation is converged!" << std::endl; @@ -173,8 +173,6 @@ bool Ions_Move_Basic::check_converged(const UnitCell &ucell, const double *grad, { ofs << "\n Ion relaxation is not converged yet (threshold is " << PARAM.inp.force_thr * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A << ")" << std::endl; - // std::cout << "\n etot_diff=" << etot_diff << " etot_thr=" << etot_thr - //<< " largest_grad=" << largest_grad << " force_thr=" << PARAM.inp.force_thr << std::endl; return false; } } @@ -213,44 +211,26 @@ void Ions_Move_Basic::terminate(const bool converged, const int update_iter, con return; } -void Ions_Move_Basic::setup_etot(const double &energy_in, const bool judgement, const int istep) +void Ions_Move_Basic::setup_etot(const double &energy_in, const bool judgement, const int istep, std::ofstream& ofs, std::vector& etot_info) { + // etot_info[0] = etot (current total energy) + // etot_info[1] = etot_p (previous total energy) + // ediff = etot_info[0] - etot_info[1] (computed on demand) + if (istep == 1) { - // p == previous - Ions_Move_Basic::etot_p = energy_in; - Ions_Move_Basic::etot = energy_in; - ediff = etot - etot_p; + etot_info[1] = energy_in; + etot_info[0] = energy_in; } else { - // mohan modify 2010-07-10 - // mohan modify again 2010-07-25 - if (judgement) // for sd - { - Ions_Move_Basic::etot = energy_in; - if (Ions_Move_Basic::etot_p > etot) - { - ediff = etot - etot_p; - Ions_Move_Basic::etot_p = etot; - } - else - { - // this step will not be accepted - ediff = 0.0; - } - } - // note: the equlibrium point is not - // need to be the smallest energy point. - else // for bfgs + etot_info[1] = etot_info[0]; + etot_info[0] = energy_in; + if (etot_info[1] > etot_info[0]) { - Ions_Move_Basic::etot_p = etot; - Ions_Move_Basic::etot = energy_in; - ediff = etot - etot_p; + etot_info[1] = etot_info[0]; } } - - return; } double Ions_Move_Basic::dot_func(const double *a, const double *b, const int &dim_in) diff --git a/source/source_relax/ions_move_basic.h b/source/source_relax/ions_move_basic.h index f38de1a65ea..b9980229649 100644 --- a/source/source_relax/ions_move_basic.h +++ b/source/source_relax/ions_move_basic.h @@ -18,12 +18,8 @@ */ namespace Ions_Move_Basic { -// Shared state variables (referenced from Relax_Data for unified data sharing) static int& dim = Relax_Data::dim; ///< Dimension of free variables (3 * number of atoms) static double& largest_grad = Relax_Data::largest_grad; ///< Largest gradient component -static double& ediff = Relax_Data::ediff; ///< Energy difference from previous step -static double& etot = Relax_Data::etot; ///< Total energy of current step -static double& etot_p = Relax_Data::etot_p; ///< Total energy of previous step // Ions-specific parameters (not shared with lattice change) extern double trust_radius; ///< Current trust radius @@ -60,9 +56,10 @@ void move_atoms(UnitCell &ucell, double *move, double *pos, std::ofstream& ofs); * @param grad Gradient array (dimension: dim) * @param update_iter Number of successfully updated iterations (will be incremented if converged) * @param ofs Output stream for logging + * @param etot_info Energy information array [etot, etot_p, ediff] * @return true if converged, false otherwise */ -bool check_converged(const UnitCell &ucell, const double *grad, int& update_iter, std::ofstream& ofs); +bool check_converged(const UnitCell &ucell, const double *grad, int& update_iter, std::ofstream& ofs, std::vector& etot_info); /** * @brief Terminate geometry optimization and output results. @@ -79,8 +76,9 @@ void terminate(const bool converged, const int update_iter, const UnitCell &ucel * @param energy_in Input energy value * @param judgement Flag for SD method (true) or BFGS (false) * @param istep Current ionic step index + * @param etot_info Energy information array [etot, etot_p, ediff] */ -void setup_etot(const double &energy_in, const bool judgement, const int istep); +void setup_etot(const double &energy_in, const bool judgement, const int istep, std::ofstream& ofs, std::vector& etot_info); /** * @brief Compute dot product of two vectors. @@ -97,4 +95,4 @@ double dot_func(const double *a, const double *b, const int &dim_in); void third_order(); } // namespace Ions_Move_Basic -#endif \ No newline at end of file +#endif diff --git a/source/source_relax/ions_move_bfgs.cpp b/source/source_relax/ions_move_bfgs.cpp index 4944f499610..3763a43ac42 100644 --- a/source/source_relax/ions_move_bfgs.cpp +++ b/source/source_relax/ions_move_bfgs.cpp @@ -37,13 +37,10 @@ void Ions_Move_BFGS::allocate() return; } -bool Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, int& update_iter, std::ofstream& ofs) +bool Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info) { ModuleBase::TITLE("Ions_Move_BFGS", "start"); - // use force to setup gradient. - // Only the first step needs to generate the pos from ucell. - // In the following steps, the pos is updated by BFGS methods. if (first_step) { Ions_Move_Basic::setup_gradient(ucell, force, this->pos.data(), this->grad.data(), ofs); @@ -54,11 +51,8 @@ bool Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con std::vector pos_tmp(3 * ucell.nat); Ions_Move_Basic::setup_gradient(ucell, force, pos_tmp.data(), this->grad.data(), ofs); } - // use energy_in and istep to setup etot and etot_old. - Ions_Move_Basic::setup_etot(energy_in, false, istep); - // use gradient and etot and etot_old to check - // if the result is converged. - bool converged = Ions_Move_Basic::check_converged(ucell, this->grad.data(), update_iter, ofs); + Ions_Move_Basic::setup_etot(energy_in, false, istep, ofs, etot_info); + bool converged = Ions_Move_Basic::check_converged(ucell, this->grad.data(), update_iter, ofs, etot_info); if (converged) { @@ -67,23 +61,8 @@ bool Ions_Move_BFGS::start(UnitCell& ucell, const ModuleBase::matrix& force, con } else { - // [ if new step ] - // reset trust_radius_old. - // [ if run from previous saved info ] - // the BFGS file is read from previous run. - // and the move_p is renormalized. this->restart_bfgs(ucell.lat0, update_iter, ofs); - - //[ if etot>etot_p ] - // interpolation - //[ if etot the new move using hessian - // matrix, and set the new trust radius. - // [compute the move at last] - this->bfgs_routine(ucell.lat0, istep, update_iter, ofs); - - // get prepared for the next try. - // even if the energy is higher, we save the information. + this->bfgs_routine(ucell.lat0, istep, update_iter, ofs, etot_info); this->save_bfgs(); Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data(), ofs); @@ -167,63 +146,27 @@ void Ions_Move_BFGS::restart_bfgs(const double& lat0, int& update_iter, std::ofs return; } -void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, int& update_iter, std::ofstream& ofs) +void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info) { ModuleBase::TITLE("Ions_Move_BFGS", "bfgs_routine"); using namespace Ions_Move_Basic; - // the bfgs algorithm starts here - if (etot > etot_p) + // etot_info[0] = etot (current total energy) + // etot_info[1] = etot_p (previous total energy) + // ediff = etot_info[0] - etot_info[1] (computed on demand) + + if (etot_info[0] > etot_info[1]) { - // the previous step is rejected, line search goes on - // we believe that we are in a correct direction, what we should do - // in this case is to find a better step length until it is accepted - - // s: trust_radius - // s': trust_radius_old - // assume: E(s) = a*s*s + b*s + c( we use E(0), dE(0), E(s') ) - // E(s') = etot - - //------------------------------------------- - // E(0) = etot_p - // ==> c = etot_p - - //------------------------------------------- - // Let's see how to calculate b. - // dE(s) = (2*a*s + b) * ds - // ==> dE(0) = b * ds - // b = dE(0)/ds = grad_p - - //------------------------------------------- - // Let's see how to calculate s. - // dE(s)/ds = 2a*s + b = 0; - // ==> s = - 0.5 * b / a - - //------------------------------------------- - // Let's see how to calculate a: - // E(s') = a*s'*s' + b*s' + etot_p = etot - // ==> a*s'*s' = etot-etot_p-b*s' - - //------------------------------------------- - // Let's see how to calculate final trust_radius - // s = -0.5 * b / a = -0.5 * (b*s'*s') / (etot-etot_p-b*s') - // s_min = - 0.5 * ( dE(0)*s'*s' ) / ( E(s') - E(0) - dE(0)*s' ) - - // just like how we estimate the step length in CG - // dE0s : b*y = averaged_grad * trust_radius_old double dE0s = 0.0; for (int i = 0; i < dim; i++) { - // because dE(s)/dR(move_p) = Force(grad) - // so dE = dR * grad dE0s += this->grad_p[i] * this->move_p[i]; } - double den = etot - etot_p - dE0s; + double den = etot_info[0] - etot_info[1] - dE0s; if (den > 1.0e-16) { - // get optimized trust radius trust_radius = -0.5 * dE0s * trust_radius_old / den; if (PARAM.inp.test_relax_method) @@ -232,19 +175,14 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, int& upda ModuleBase::GlobalFunc::OUT(ofs, "den", den); ModuleBase::GlobalFunc::OUT(ofs, "interpolated trust radius", trust_radius); } - // std::cout << " Formula : " << etot << " * s^2 + " << dE0s << " * s + " << etot_p << std::endl; - // std::cout << " Lowest point : " << trust_radius << std::endl; } else if (den <= 1.0e-16) { - // no quadratic interpolation is possible - // then do is again, but smaller raidus. trust_radius = 0.5 * trust_radius_old; - ofs << " quadratic interpolation is impossible." << std::endl; } - // values from the last succeseful bfgs step are restored - etot = etot_p; + + etot_info[0] = etot_info[1]; for (int i = 0; i < dim; i++) { this->pos[i] = pos_p[i]; @@ -253,19 +191,13 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, int& upda if (trust_radius < relax_bfgs_rmin) { - // we are trapped in this case..., so the algorithim must be restart - // the history is reset - // xiaohui add 2013-03-17 ofs << "trust_radius = " << trust_radius << std::endl; ofs << "relax_bfgs_rmin = " << relax_bfgs_rmin << std::endl; ofs << "relax_bfgs_rmax = " << relax_bfgs_rmax << std::endl; - // xiaohui add 2013-03-17 ofs << " trust_radius < relax_bfgs_rmin, reset bfgs history." << std::endl; if (tr_min_hit) { - // the history has already been reset at the previous step - // something is going wrong ModuleBase::WARNING_QUIT("move_ions", "trust radius is too small! Break down."); } @@ -277,12 +209,10 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, int& upda } trust_radius = relax_bfgs_rmin; - tr_min_hit = true; } else if (trust_radius >= relax_bfgs_rmin) { - // old bfgs direction ( normalized ) is recovered for (int i = 0; i < dim; i++) { this->move[i] = this->move_p[i] / trust_radius_old; @@ -290,9 +220,9 @@ void Ions_Move_BFGS::bfgs_routine(const double& lat0, const int istep, int& upda tr_min_hit = false; } } - else if (etot <= etot_p) + else if (etot_info[0] <= etot_info[1]) { - this->new_step(lat0, update_iter, ofs); + this->new_step(lat0, update_iter, ofs, etot_info); } if (PARAM.inp.out_level == "ie") diff --git a/source/source_relax/ions_move_bfgs.h b/source/source_relax/ions_move_bfgs.h index 863db2e2533..9c6ee2ef508 100644 --- a/source/source_relax/ions_move_bfgs.h +++ b/source/source_relax/ions_move_bfgs.h @@ -3,6 +3,7 @@ #include #include +#include #include "bfgs_basic.h" #include "source_base/matrix.h" #include "source_cell/unitcell.h" @@ -13,11 +14,11 @@ class Ions_Move_BFGS : public BFGS_Basic ~Ions_Move_BFGS(); void allocate(void); - bool start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, int& update_iter, std::ofstream& ofs); + bool start(UnitCell& ucell, const ModuleBase::matrix& force, const double& energy_in, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info); private: bool init_done; - void bfgs_routine(const double& lat0, const int istep, int& update_iter, std::ofstream& ofs); + void bfgs_routine(const double& lat0, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info); void restart_bfgs(const double& lat0, int& update_iter, std::ofstream& ofs); bool first_step=true; // If it is the first step of the relaxation. The pos is only generated from ucell in the first step, and in the following steps, the pos is generated from the previous step. }; diff --git a/source/source_relax/ions_move_cg.cpp b/source/source_relax/ions_move_cg.cpp index 3ed81874683..9c3a576b57d 100644 --- a/source/source_relax/ions_move_cg.cpp +++ b/source/source_relax/ions_move_cg.cpp @@ -23,7 +23,7 @@ void Ions_Move_CG::allocate(const int dim) this->e0 = 0.0; } -bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, const int istep, int& update_iter, std::ofstream& ofs) +bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info) { ModuleBase::TITLE("Ions_Move_CG", "start"); assert(Ions_Move_Basic::dim > 0); @@ -72,12 +72,12 @@ bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const } Ions_Move_Basic::setup_gradient(ucell, force, pos.data(), grad.data(), ofs); - Ions_Move_Basic::setup_etot(etot_in, 0, istep); + Ions_Move_Basic::setup_etot(etot_in, 0, istep, ofs, etot_info); bool converged = false; if (flag == 0) { - converged = Ions_Move_Basic::check_converged(ucell, grad.data(), update_iter, ofs); + converged = Ions_Move_Basic::check_converged(ucell, grad.data(), update_iter, ofs, etot_info); } if (converged) { diff --git a/source/source_relax/ions_move_cg.h b/source/source_relax/ions_move_cg.h index 063a5442647..186cb4b1e03 100644 --- a/source/source_relax/ions_move_cg.h +++ b/source/source_relax/ions_move_cg.h @@ -15,7 +15,7 @@ class Ions_Move_CG : public CG_Base ~Ions_Move_CG() = default; void allocate(const int dim); - bool start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, const int istep, int& update_iter, std::ofstream& ofs); + bool start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info); static double RELAX_CG_THR; int sd_step = 0; diff --git a/source/source_relax/ions_move_methods.cpp b/source/source_relax/ions_move_methods.cpp index c1df2be53b2..e1452721c7c 100644 --- a/source/source_relax/ions_move_methods.cpp +++ b/source/source_relax/ions_move_methods.cpp @@ -63,18 +63,19 @@ void Ions_Move_Methods::cal_movement(const int &istep, ModuleBase::TITLE("Ions_Move_Methods", "init"); if (Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] != "1") { - // move_ions - // output tau - // check all symmery - converged_ = bfgs.start(ucell, f, etot, force_step, update_iter_, ofs); + converged_ = bfgs.start(ucell, f, etot, force_step, update_iter_, ofs, etot_info_); + } + else if (Ions_Move_Basic::relax_method[0] == "sd") + { + converged_ = sd.start(ucell, f, etot, force_step, update_iter_, ofs, etot_info_); } else if (Ions_Move_Basic::relax_method[0] == "cg") { - converged_ = cg.start(ucell, f, etot, force_step, update_iter_, ofs); + converged_ = cg.start(ucell, f, etot, force_step, update_iter_, ofs, etot_info_); } else if (Ions_Move_Basic::relax_method[0] == "cg_bfgs") { - converged_ = cg.start(ucell, f, etot, force_step, update_iter_, ofs); // added by pengfei 13-8-10 + converged_ = cg.start(ucell, f, etot, force_step, update_iter_, ofs, etot_info_); } else if(Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] == "1") { diff --git a/source/source_relax/ions_move_methods.h b/source/source_relax/ions_move_methods.h index b5bf206b7c2..202372a395e 100644 --- a/source/source_relax/ions_move_methods.h +++ b/source/source_relax/ions_move_methods.h @@ -3,6 +3,7 @@ #include #include +#include #include "ions_move_basic.h" #include "ions_move_bfgs.h" #include "ions_move_cg.h" @@ -17,7 +18,6 @@ class Ions_Move_Methods ~Ions_Move_Methods(); void allocate(const int &natom, const std::string& relax_method_0, const std::string& relax_method_1); - // void cal_movement(const int &istep, const ModuleBase::matrix &f, const double &etot); void cal_movement(const int &istep, const int &force_step, const ModuleBase::matrix &f, @@ -32,7 +32,7 @@ class Ions_Move_Methods double get_ediff() const { - return Ions_Move_Basic::ediff; + return etot_info_[0] - etot_info_[1]; } double get_largest_grad() const { @@ -55,5 +55,6 @@ class Ions_Move_Methods Ions_Move_LBFGS lbfgs; bool converged_ = false; int update_iter_ = 0; + std::vector etot_info_{2, 0.0}; // [etot, etot_p] }; #endif diff --git a/source/source_relax/ions_move_sd.cpp b/source/source_relax/ions_move_sd.cpp index ca87a9e45e3..276297ef8eb 100644 --- a/source/source_relax/ions_move_sd.cpp +++ b/source/source_relax/ions_move_sd.cpp @@ -20,7 +20,7 @@ void Ions_Move_SD::allocate() pos_saved.resize(dim, 0.0); } -bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot_in, const int istep, int& update_iter, std::ofstream& ofs) +bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot_in, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info) { ModuleBase::TITLE("Ions_Move_SD", "start"); @@ -32,10 +32,8 @@ bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const std::vector grad(dim, 0.0); std::vector move(dim, 0.0); - // 1: ediff = 0 - // 0: ediff < 0 bool judgement = false; - Ions_Move_Basic::setup_etot(etot_in, judgement, istep); + Ions_Move_Basic::setup_etot(etot_in, judgement, istep, ofs, etot_info); Ions_Move_Basic::setup_gradient(ucell, force, pos.data(), grad.data(), ofs); if (istep == 1 || etot_in <= energy_saved) @@ -51,8 +49,6 @@ bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const { grad_saved[i] = grad[i]; } - // normalize the gradient, in convinience to - // move atom. double norm = dot_func(grad_saved.data(), grad_saved.data(), dim); norm = sqrt(norm); for (int i = 0; i < dim; i++) @@ -61,7 +57,7 @@ bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const } } - bool converged = Ions_Move_Basic::check_converged(ucell, grad.data(), update_iter, ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad.data(), update_iter, ofs, etot_info); if (converged) { Ions_Move_Basic::terminate(converged, update_iter, ucell, istep, ofs); @@ -69,7 +65,7 @@ bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const } else { - this->cal_tradius_sd(istep); + this->cal_tradius_sd(istep, etot_info); for (int i = 0; i < dim; i++) { move[i] = -grad_saved[i] * trust_radius; @@ -80,7 +76,7 @@ bool Ions_Move_SD::start(UnitCell& ucell, const ModuleBase::matrix& force, const } } -void Ions_Move_SD::cal_tradius_sd(const int istep) const +void Ions_Move_SD::cal_tradius_sd(const int istep, std::vector& etot_info) const { static int accepted_number = 0; @@ -90,7 +86,8 @@ void Ions_Move_SD::cal_tradius_sd(const int istep) const } else if (istep > 1) { - if (Ions_Move_Basic::ediff < 0.0) + const double ediff = etot_info[0] - etot_info[1]; + if (ediff < 0.0) { accepted_number++; if (accepted_number > 3 && accepted_number % 3 == 1) @@ -98,7 +95,7 @@ void Ions_Move_SD::cal_tradius_sd(const int istep) const Ions_Move_Basic::trust_radius *= 1.5; } } - else if (Ions_Move_Basic::ediff >= 0.0) // == 0 means no accept! + else if (ediff >= 0.0) { accepted_number = 0; Ions_Move_Basic::trust_radius *= 0.5; diff --git a/source/source_relax/ions_move_sd.h b/source/source_relax/ions_move_sd.h index d59568efb81..3b209d3e9c1 100644 --- a/source/source_relax/ions_move_sd.h +++ b/source/source_relax/ions_move_sd.h @@ -14,14 +14,14 @@ class Ions_Move_SD ~Ions_Move_SD() = default; void allocate(void); - bool start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot, const int istep, int& update_iter, std::ofstream& ofs); + bool start(UnitCell& ucell, const ModuleBase::matrix& force, const double& etot, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info); private: double energy_saved; std::vector pos_saved; std::vector grad_saved; - void cal_tradius_sd(const int istep) const; + void cal_tradius_sd(const int istep, std::vector& etot_info) const; }; #endif diff --git a/source/source_relax/test/bfgs_basic_test.cpp b/source/source_relax/test/bfgs_basic_test.cpp index f69f76a036e..75895b4fdcd 100644 --- a/source/source_relax/test/bfgs_basic_test.cpp +++ b/source/source_relax/test/bfgs_basic_test.cpp @@ -113,15 +113,15 @@ TEST_F(BFGSBasicTest, UpdateInverseHessianCase2) TEST_F(BFGSBasicTest, CheckWolfeConditions) { Ions_Move_Basic::dim = 3; - Ions_Move_Basic::etot = 10.0; PARAM.input.test_relax_method = 1; bfgs.allocate_basic(); bfgs.pos[0] = 2.0; bfgs.grad[0] = 2.0; bfgs.move[0] = 1.0; + std::vector etot_info = {10.0, 0.0}; std::ofstream ofs("test_log_check_wolfe_conditions.log"); - bfgs.check_wolfe_conditions(ofs); + bfgs.check_wolfe_conditions(ofs, etot_info); ofs.close(); std::string expected_output @@ -203,7 +203,8 @@ TEST_F(BFGSBasicTest, NewStepCase1) double lat0 = 1.0; std::ofstream ofs("test_log.log"); - bfgs.new_step(lat0, update_iter, ofs); + std::vector etot_info(2, 0.0); + bfgs.new_step(lat0, update_iter, ofs, etot_info); EXPECT_EQ(update_iter, 1); EXPECT_EQ(bfgs.tr_min_hit, false); @@ -237,7 +238,8 @@ TEST_F(BFGSBasicTest, NewStepCase2) double lat0 = 1.0; std::ofstream ofs("test_log.log"); - bfgs.new_step(lat0, update_iter, ofs); + std::vector etot_info(2, 0.0); + bfgs.new_step(lat0, update_iter, ofs, etot_info); EXPECT_EQ(update_iter, 3); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, -1.0); @@ -258,9 +260,10 @@ TEST_F(BFGSBasicTest, NewStepWarningQuit) bfgs.allocate_basic(); double lat0 = 1.0; std::ofstream ofs("test_log.log"); + std::vector etot_info(2, 0.0); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.new_step(lat0, update_iter, ofs), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.new_step(lat0, update_iter, ofs, etot_info), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("bfgs_ndim > 1 not implemented yet")); } @@ -269,8 +272,6 @@ TEST_F(BFGSBasicTest, NewStepWarningQuit) TEST_F(BFGSBasicTest, ComputeTrustRadiusCase1) { Ions_Move_Basic::dim = 2; - Ions_Move_Basic::etot = 0.0; - Ions_Move_Basic::etot_p = 0.0; bfgs.allocate_basic(); bfgs.grad_p[0] = 1.0; bfgs.move_p[1] = 2.0; @@ -280,9 +281,10 @@ TEST_F(BFGSBasicTest, ComputeTrustRadiusCase1) bfgs.inv_hess(1, 1) = -6.0; bfgs.wolfe_flag = true; bfgs.relax_bfgs_w1 = 1.0; + std::vector etot_info = {0.0, 0.0, 0.0}; std::ofstream ofs("test_log.log"); - bfgs.compute_trust_radius(ofs); + bfgs.compute_trust_radius(ofs, etot_info); EXPECT_EQ(bfgs.tr_min_hit, false); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, -1.0); @@ -298,8 +300,6 @@ TEST_F(BFGSBasicTest, ComputeTrustRadiusCase1) TEST_F(BFGSBasicTest, ComputeTrustRadiusCase2) { Ions_Move_Basic::dim = 2; - Ions_Move_Basic::etot = 0.0; - Ions_Move_Basic::etot_p = 0.0; Ions_Move_Basic::trust_radius_old = 0.0; Ions_Move_Basic::relax_bfgs_rmin = 100.0; PARAM.input.test_relax_method = 1; @@ -314,9 +314,10 @@ TEST_F(BFGSBasicTest, ComputeTrustRadiusCase2) bfgs.wolfe_flag = false; bfgs.relax_bfgs_w1 = 1.0; bfgs.tr_min_hit = false; + std::vector etot_info = {0.0, 0.0, 0.0}; std::ofstream ofs("test_log.log"); - bfgs.compute_trust_radius(ofs); + bfgs.compute_trust_radius(ofs, etot_info); EXPECT_EQ(bfgs.tr_min_hit, true); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, 100.0); @@ -332,8 +333,6 @@ TEST_F(BFGSBasicTest, ComputeTrustRadiusCase2) TEST_F(BFGSBasicTest, ComputeTrustRadiusWarningQuit) { Ions_Move_Basic::dim = 2; - Ions_Move_Basic::etot = 0.0; - Ions_Move_Basic::etot_p = 0.0; Ions_Move_Basic::trust_radius_old = 0.0; Ions_Move_Basic::relax_bfgs_rmin = 100.0; PARAM.input.test_relax_method = 1; @@ -348,10 +347,11 @@ TEST_F(BFGSBasicTest, ComputeTrustRadiusWarningQuit) bfgs.wolfe_flag = false; bfgs.relax_bfgs_w1 = 1.0; bfgs.tr_min_hit = true; + std::vector etot_info = {0.0, 0.0, 0.0}; std::ofstream ofs("test_log.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.compute_trust_radius(ofs), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.compute_trust_radius(ofs, etot_info), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("bfgs history already reset at previous step, we got trapped!")); } \ No newline at end of file diff --git a/source/source_relax/test/ions_move_basic_test.cpp b/source/source_relax/test/ions_move_basic_test.cpp index 0bc70327ba0..7b6598cac51 100644 --- a/source/source_relax/test/ions_move_basic_test.cpp +++ b/source/source_relax/test/ions_move_basic_test.cpp @@ -105,6 +105,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase1) int update_iter = 1; PARAM.input.test_relax_method = 1; PARAM.input.out_level = "ie"; + std::vector etot_info(2, 0.0); for (int i = 0; i < Ions_Move_Basic::dim; ++i) { grad[i] = 0.0; @@ -113,7 +114,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase1) // Call the function being tested std::ofstream ofs("test_check_converged_case1.log"); testing::internal::CaptureStdout(); - bool converged = Ions_Move_Basic::check_converged(ucell, grad, update_iter, ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad, update_iter, ofs, etot_info); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -143,7 +144,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase2) // Initialize data Ions_Move_Basic::dim = 6; int update_iter = 1; - Ions_Move_Basic::ediff = 0.0; + std::vector etot_info(2, 0.0); PARAM.input.test_relax_method = 1; PARAM.input.out_level = "ie"; PARAM.input.force_thr = 1.0; @@ -152,7 +153,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase2) // Call the function being tested std::ofstream ofs("test_check_converged_case2.log"); testing::internal::CaptureStdout(); - bool converged = Ions_Move_Basic::check_converged(ucell, grad, update_iter, ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad, update_iter, ofs, etot_info); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -182,7 +183,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase3) // Initialize data Ions_Move_Basic::dim = 6; int update_iter = 1; - Ions_Move_Basic::ediff = 1.0; + std::vector etot_info = {1.0, 0.0}; PARAM.input.test_relax_method = 1; PARAM.input.out_level = "ie"; PARAM.input.force_thr = 1.0; @@ -191,7 +192,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase3) // Call the function being tested std::ofstream ofs("test_check_converged_case3.log"); testing::internal::CaptureStdout(); - bool converged = Ions_Move_Basic::check_converged(ucell, grad, update_iter, ofs); + bool converged = Ions_Move_Basic::check_converged(ucell, grad, update_iter, ofs, etot_info); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -202,7 +203,7 @@ TEST_F(IonsMoveBasicTest, CheckConvergedCase3) std::remove("test_check_converged_case3.log"); std::string expected_ofs - = " old total energy (ry) = 0\n new total energy (ry) = 0\n " + = " old total energy (ry) = 0\n new total energy (ry) = 1\n " " energy difference (ry) = 1\n largest gradient (ry/bohr) = 0.1\n\n" " Largest force is 2.57111 eV/Angstrom while threshold is -1 eV/Angstrom\n\n Ion relaxation is not " "converged yet (threshold is 25.7111)\n"; @@ -269,19 +270,19 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase1) { // Initialize data const int istep = 1; - Ions_Move_Basic::etot_p = 1.0; - Ions_Move_Basic::etot = 2.0; - Ions_Move_Basic::ediff = 0.0; + std::vector etot_info = {2.0, 1.0, 0.0}; double energy_in = 3.0; bool judgement = true; // Call the function being tested - Ions_Move_Basic::setup_etot(energy_in, judgement, istep); + std::ofstream ofs("/dev/null"); + Ions_Move_Basic::setup_etot(energy_in, judgement, istep, ofs, etot_info); + ofs.close(); // Check the results - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot_p, 3.0); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot, 3.0); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::ediff, 0.0); + EXPECT_DOUBLE_EQ(etot_info[1], 3.0); + EXPECT_DOUBLE_EQ(etot_info[0], 3.0); + EXPECT_DOUBLE_EQ(etot_info[0] - etot_info[1], 0.0); } // Test the setup_etot() function case 2 @@ -289,19 +290,19 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase2) { // Initialize data const int istep = 2; - Ions_Move_Basic::etot_p = 4.0; - Ions_Move_Basic::etot = 2.0; - Ions_Move_Basic::ediff = 0.0; + std::vector etot_info = {2.0, 4.0}; double energy_in = 3.0; bool judgement = true; // Call the function being tested - Ions_Move_Basic::setup_etot(energy_in, judgement, istep); + std::ofstream ofs("/dev/null"); + Ions_Move_Basic::setup_etot(energy_in, judgement, istep, ofs, etot_info); + ofs.close(); // Check the results - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot_p, 3.0); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot, 3.0); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::ediff, -1.0); + EXPECT_DOUBLE_EQ(etot_info[1], 2.0); + EXPECT_DOUBLE_EQ(etot_info[0], 3.0); + EXPECT_DOUBLE_EQ(etot_info[0] - etot_info[1], 1.0); } // Test the setup_etot() function case 3 @@ -309,19 +310,19 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase3) { // Initialize data const int istep = 2; - Ions_Move_Basic::etot_p = 1.0; - Ions_Move_Basic::etot = 2.0; - Ions_Move_Basic::ediff = 0.0; + std::vector etot_info = {2.0, 1.0}; double energy_in = 3.0; bool judgement = true; // Call the function being tested - Ions_Move_Basic::setup_etot(energy_in, judgement, istep); + std::ofstream ofs("/dev/null"); + Ions_Move_Basic::setup_etot(energy_in, judgement, istep, ofs, etot_info); + ofs.close(); // Check the results - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot_p, 1.0); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot, 3.0); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::ediff, 0.0); + EXPECT_DOUBLE_EQ(etot_info[1], 2.0); + EXPECT_DOUBLE_EQ(etot_info[0], 3.0); + EXPECT_DOUBLE_EQ(etot_info[0] - etot_info[1], 1.0); } // Test the setup_etot() function case 4 @@ -329,19 +330,19 @@ TEST_F(IonsMoveBasicTest, SetupEtotCase4) { // Initialize data const int istep = 2; - Ions_Move_Basic::etot_p = 1.0; - Ions_Move_Basic::etot = 2.0; - Ions_Move_Basic::ediff = 0.0; + std::vector etot_info = {2.0, 1.0}; double energy_in = 3.0; bool judgement = false; // Call the function being tested - Ions_Move_Basic::setup_etot(energy_in, judgement, istep); + std::ofstream ofs("/dev/null"); + Ions_Move_Basic::setup_etot(energy_in, judgement, istep, ofs, etot_info); + ofs.close(); // Check the results - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot_p, 2.0); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot, 3.0); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::ediff, 1.0); + EXPECT_DOUBLE_EQ(etot_info[1], 2.0); + EXPECT_DOUBLE_EQ(etot_info[0], 3.0); + EXPECT_DOUBLE_EQ(etot_info[0] - etot_info[1], 1.0); } // Test the dot_func() function diff --git a/source/source_relax/test/ions_move_bfgs_test.cpp b/source/source_relax/test/ions_move_bfgs_test.cpp index 6efaa1402e9..b535166a66b 100644 --- a/source/source_relax/test/ions_move_bfgs_test.cpp +++ b/source/source_relax/test/ions_move_bfgs_test.cpp @@ -73,11 +73,12 @@ TEST_F(IonsMoveBFGSTest, StartCase1) const int istep = 1; bfgs.init_done = false; bfgs.save_flag = true; + std::vector etot_info(2, 0.0); // Call the function being tested bfgs.allocate(); std::ofstream ofs("test_start_case1.log"); - bfgs.start(ucell, force, energy_in, istep, update_iter, ofs); + bfgs.start(ucell, force, energy_in, istep, update_iter, ofs, etot_info); ofs.close(); // Check the results @@ -121,11 +122,12 @@ TEST_F(IonsMoveBFGSTest, StartCase2) double energy_in = 0.0; bfgs.init_done = false; bfgs.save_flag = true; + std::vector etot_info(2, 0.0); // Call the function being tested bfgs.allocate(); std::ofstream ofs("test_start_case2.log"); - bfgs.start(ucell, force, energy_in, istep, update_iter, ofs); + bfgs.start(ucell, force, energy_in, istep, update_iter, ofs, etot_info); ofs.close(); // Check the results @@ -233,8 +235,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase1) PARAM.input.out_level = "ie"; double lat0 = 1.0; const int istep = 1; - Ions_Move_Basic::etot = 1.0; - Ions_Move_Basic::etot_p = 0.9; + std::vector etot_info = {1.0, 0.9, 0.1}; Ions_Move_Basic::relax_bfgs_rmin = 1.0; for (int i = 0; i < Ions_Move_Basic::dim; ++i) { @@ -246,7 +247,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase1) // Call the function being tested std::ofstream ofs("test_bfgs_routine_case1.log"); testing::internal::CaptureStdout(); - bfgs.bfgs_routine(lat0, istep, update_iter, ofs); + bfgs.bfgs_routine(lat0, istep, update_iter, ofs, etot_info); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -266,7 +267,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase1) EXPECT_EQ(expected_std, std_outout); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, 1.0); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot, 0.9); + EXPECT_DOUBLE_EQ(etot_info[0], 0.9); EXPECT_DOUBLE_EQ(bfgs.tr_min_hit, true); EXPECT_NEAR(bfgs.move[0], 0.0, 1e-12); EXPECT_NEAR(bfgs.move[1], -0.13483997249264842, 1e-12); @@ -299,8 +300,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase2) PARAM.input.out_level = "none"; double lat0 = 1.0; const int istep = 1; - Ions_Move_Basic::etot = 1.0; - Ions_Move_Basic::etot_p = 0.9; + std::vector etot_info = {1.0, 0.9, 0.1}; Ions_Move_Basic::relax_bfgs_rmin = -1.0; for (int i = 0; i < Ions_Move_Basic::dim; ++i) { @@ -312,7 +312,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase2) // Call the function being tested std::ofstream ofs("test_bfgs_routine_case2.log"); testing::internal::CaptureStdout(); - bfgs.bfgs_routine(lat0, istep, update_iter, ofs); + bfgs.bfgs_routine(lat0, istep, update_iter, ofs, etot_info); std::string std_outout = testing::internal::GetCapturedStdout(); ofs.close(); @@ -329,7 +329,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase2) EXPECT_EQ(expected_std, std_outout); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, -0.5); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot, 0.9); + EXPECT_DOUBLE_EQ(etot_info[0], 0.9); EXPECT_DOUBLE_EQ(bfgs.tr_min_hit, false); EXPECT_NEAR(bfgs.move[0], 0.0, 1e-12); EXPECT_NEAR(bfgs.move[1], 0.067419986246324212, 1e-12); @@ -354,8 +354,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase3) // Initilize data double lat0 = 1.0; const int istep = 1; - Ions_Move_Basic::etot = 0.9; - Ions_Move_Basic::etot_p = 1.0; + std::vector etot_info = {0.9, 1.0, -0.1}; update_iter = 0; Ions_Move_Basic::largest_grad = 0.0; Ions_Move_Basic::relax_bfgs_init = 0.3; @@ -372,7 +371,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase3) // Call the function being tested std::ofstream ofs("test_bfgs_routine_case3.log"); - bfgs.bfgs_routine(lat0, istep, update_iter, ofs); + bfgs.bfgs_routine(lat0, istep, update_iter, ofs, etot_info); ofs.close(); // Check the results @@ -385,7 +384,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineCase3) EXPECT_THAT(ofs_output, ::testing::HasSubstr(expected_ofs)); EXPECT_DOUBLE_EQ(Ions_Move_Basic::trust_radius, 0.2); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::etot, 0.9); + EXPECT_DOUBLE_EQ(etot_info[0], 0.9); EXPECT_DOUBLE_EQ(bfgs.tr_min_hit, false); EXPECT_NEAR(bfgs.move[0], -0.089442719099991588, 1e-12); EXPECT_NEAR(bfgs.move[1], -0.17888543819998318, 1e-12); @@ -418,8 +417,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit1) PARAM.input.out_level = "ie"; double lat0 = 1.0; const int istep = 1; - Ions_Move_Basic::etot = 1.0; - Ions_Move_Basic::etot_p = 0.9; + std::vector etot_info = {1.0, 0.9, 0.1}; Ions_Move_Basic::relax_bfgs_rmin = 1.0; for (int i = 0; i < Ions_Move_Basic::dim; ++i) { @@ -431,7 +429,7 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit1) // Check the results std::ofstream ofs("test_bfgs_routine_warning_quit1.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.bfgs_routine(lat0, istep, update_iter, ofs), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.bfgs_routine(lat0, istep, update_iter, ofs, etot_info), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); ofs.close(); std::remove("test_bfgs_routine_warning_quit1.log"); @@ -449,14 +447,13 @@ TEST_F(IonsMoveBFGSTest, BfgsRoutineWarningQuit2) PARAM.input.out_level = "ie"; double lat0 = 1.0; const int istep = 1; - Ions_Move_Basic::etot = 1.0; - Ions_Move_Basic::etot_p = 0.9; + std::vector etot_info = {1.0, 0.9, 0.1}; Ions_Move_Basic::relax_bfgs_rmin = 1.0; // Check the results std::ofstream ofs("test_bfgs_routine_warning_quit2.log"); testing::internal::CaptureStdout(); - EXPECT_EXIT(bfgs.bfgs_routine(lat0, istep, update_iter, ofs), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(bfgs.bfgs_routine(lat0, istep, update_iter, ofs, etot_info), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); ofs.close(); std::remove("test_bfgs_routine_warning_quit2.log"); diff --git a/source/source_relax/test/ions_move_cg_test.cpp b/source/source_relax/test/ions_move_cg_test.cpp index 9fd38da2420..b86c70254e3 100644 --- a/source/source_relax/test/ions_move_cg_test.cpp +++ b/source/source_relax/test/ions_move_cg_test.cpp @@ -97,10 +97,11 @@ TEST_F(IonsMoveCGTest, TestStartConverged) setupucell(ucell); ModuleBase::matrix force(2, 3); double etot = 0.0; + std::vector etot_info(2, 0.0); // call function std::ofstream ofs("TestStartConverged.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs); + im_cg.start(ucell, force, etot, istep, update_iter, ofs, etot_info); ofs.close(); // Check output @@ -133,10 +134,11 @@ TEST_F(IonsMoveCGTest, TestStartSd) ModuleBase::matrix force(2, 3); force(0, 0) = 0.01; double etot = 0.0; + std::vector etot_info(2, 0.0); // call function std::ofstream ofs("TestStartSd.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs); + im_cg.start(ucell, force, etot, istep, update_iter, ofs, etot_info); ofs.close(); // Check output @@ -165,18 +167,19 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) ModuleBase::matrix force(2, 3); force(0, 0) = 0.1; double etot = 0.0; + std::vector etot_info(2, 0.0); // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartTrialGoto_temp1.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs1); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info); ofs1.close(); std::remove("TestStartTrialGoto_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 10.0; force(0, 0) = 0.001; std::ofstream ofs("TestStartTrialGoto.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info); ofs.close(); // Check output @@ -205,17 +208,18 @@ TEST_F(IonsMoveCGTest, TestStartTrial) ModuleBase::matrix force(2, 3); force(0, 0) = 0.01; double etot = 0.0; + std::vector etot_info(2, 0.0); // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartTrial_temp1.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs1); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info); ofs1.close(); std::remove("TestStartTrial_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 10.0; std::ofstream ofs("TestStartTrial.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info); ofs.close(); // Check output @@ -244,22 +248,23 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) ModuleBase::matrix force(2, 3); force(0, 0) = 0.1; double etot = 0.0; + std::vector etot_info(2, 0.0); // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrialGotoCase1_temp1.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs1); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info); ofs1.close(); std::remove("TestStartNoTrialGotoCase1_temp1.log"); int istep_2 = 2; std::ofstream ofs2("TestStartNoTrialGotoCase1_temp2.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2, etot_info); ofs2.close(); std::remove("TestStartNoTrialGotoCase1_temp2.log"); im_cg.move0[0] = 1.0; force(0, 0) = 0.001; std::ofstream ofs("TestStartNoTrialGotoCase1.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info); ofs.close(); // Check output @@ -288,21 +293,22 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) ModuleBase::matrix force(2, 3); force(0, 0) = 0.01; double etot = 0.0; + std::vector etot_info(2, 0.0); // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrialGotoCase2_temp1.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs1); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info); ofs1.close(); std::remove("TestStartNoTrialGotoCase2_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 10.0; std::ofstream ofs2("TestStartNoTrialGotoCase2_temp2.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2, etot_info); ofs2.close(); std::remove("TestStartNoTrialGotoCase2_temp2.log"); std::ofstream ofs("TestStartNoTrialGotoCase2.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info); ofs.close(); // Check output @@ -331,22 +337,23 @@ TEST_F(IonsMoveCGTest, TestStartNoTrial) ModuleBase::matrix force(2, 3); force(0, 0) = 0.01; double etot = 0.0; + std::vector etot_info(2, 0.0); // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrial_temp1.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs1); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info); ofs1.close(); std::remove("TestStartNoTrial_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 1.0; force(0, 0) = 0.001; std::ofstream ofs2("TestStartNoTrial_temp2.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2, etot_info); ofs2.close(); std::remove("TestStartNoTrial_temp2.log"); std::ofstream ofs("TestStartNoTrial.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info); ofs.close(); // Check output diff --git a/source/source_relax/test/ions_move_methods_test.cpp b/source/source_relax/test/ions_move_methods_test.cpp index bd63dcec176..13f4d8432a5 100644 --- a/source/source_relax/test/ions_move_methods_test.cpp +++ b/source/source_relax/test/ions_move_methods_test.cpp @@ -182,9 +182,8 @@ TEST_F(IonsMoveMethodsTest, CalMovementWarningQuit) // Test the get_ediff() function TEST_F(IonsMoveMethodsTest, GetEdiff) { - Ions_Move_Basic::ediff = 1.0; - - EXPECT_DOUBLE_EQ(imm.get_ediff(), 1.0); + // etot_info_ is initialized to {0.0, 0.0, 0.0} by default + EXPECT_DOUBLE_EQ(imm.get_ediff(), 0.0); } // Test the get_largest_grad() function diff --git a/source/source_relax/test/ions_move_sd_test.cpp b/source/source_relax/test/ions_move_sd_test.cpp index de0ad019c93..36a8d384dea 100644 --- a/source/source_relax/test/ions_move_sd_test.cpp +++ b/source/source_relax/test/ions_move_sd_test.cpp @@ -72,10 +72,11 @@ TEST_F(IonsMoveSDTest, TestStartConverged) UnitCell ucell; ModuleBase::matrix force(2, 3); double etot = 0.0; + std::vector etot_info(2, 0.0); // call function std::ofstream ofs("test_sd_start_converged.log"); - im_sd.start(ucell, force, etot, istep, update_iter, ofs); + im_sd.start(ucell, force, etot, istep, update_iter, ofs, etot_info); ofs.close(); // Check output @@ -111,6 +112,7 @@ TEST_F(IonsMoveSDTest, TestStartNotConverged) ModuleBase::matrix force(2, 3); force(0, 0) = 1.0; double etot = 0.0; + std::vector etot_info(2, 0.0); for (int it = 0; it < ucell.ntype; it++) { Atom* atom = &ucell.atoms[it]; @@ -126,7 +128,7 @@ TEST_F(IonsMoveSDTest, TestStartNotConverged) // call function std::ofstream ofs("test_sd_start_not_converged.log"); - im_sd.start(ucell, force, etot, istep, update_iter, ofs); + im_sd.start(ucell, force, etot, istep, update_iter, ofs, etot_info); ofs.close(); // Check output @@ -161,10 +163,11 @@ TEST_F(IonsMoveSDTest, CalTradiusSdCase1) // setup data const int istep = 1; PARAM.input.out_level = "ie"; + std::vector etot_info(2, 0.0); // call function testing::internal::CaptureStdout(); - im_sd.cal_tradius_sd(istep); + im_sd.cal_tradius_sd(istep, etot_info); std::string std_outout = testing::internal::GetCapturedStdout(); // Check the results @@ -178,11 +181,11 @@ TEST_F(IonsMoveSDTest, CalTradiusSdCase2) { // setup data const int istep = 2; - Ions_Move_Basic::ediff = -1.0; + std::vector etot_info = {0.0, 1.0}; PARAM.input.out_level = "m"; // call function - im_sd.cal_tradius_sd(istep); + im_sd.cal_tradius_sd(istep, etot_info); // Check the results EXPECT_EQ(Ions_Move_Basic::trust_radius, -1.0); @@ -193,11 +196,11 @@ TEST_F(IonsMoveSDTest, CalTradiusSdCase3) { // setup data const int istep = 2; - Ions_Move_Basic::ediff = 1.0; + std::vector etot_info = {1.0, 0.0}; PARAM.input.out_level = "m"; // call function - im_sd.cal_tradius_sd(istep); + im_sd.cal_tradius_sd(istep, etot_info); // Check the results EXPECT_EQ(Ions_Move_Basic::trust_radius, -0.5); @@ -208,10 +211,11 @@ TEST_F(IonsMoveSDTest, CalTradiusWraningQuit) { // setup data const int istep = 0; + std::vector etot_info(2, 0.0); // Check the results testing::internal::CaptureStdout(); - EXPECT_EXIT(im_sd.cal_tradius_sd(istep), ::testing::ExitedWithCode(1), ""); + EXPECT_EXIT(im_sd.cal_tradius_sd(istep, etot_info), ::testing::ExitedWithCode(1), ""); std::string output = testing::internal::GetCapturedStdout(); EXPECT_THAT(output, testing::HasSubstr("istep < 1!")); } From 121aa8a88b09c3cfe8544175a068cfb7a66af00e Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 15 Jun 2026 13:05:34 +0800 Subject: [PATCH 45/50] update, remove variables --- source/source_relax/lattice_change_basic.cpp | 28 ++++++------- source/source_relax/lattice_change_basic.h | 13 +++--- source/source_relax/lattice_change_cg.cpp | 4 +- source/source_relax/lattice_change_cg.h | 2 +- .../source_relax/lattice_change_methods.cpp | 3 +- source/source_relax/lattice_change_methods.h | 4 +- source/source_relax/relax_data.cpp | 4 -- source/source_relax/relax_data.h | 6 +-- .../test/lattice_change_basic_test.cpp | 40 ++++++++++--------- .../test/lattice_change_cg_test.cpp | 32 ++++++++------- .../test/lattice_change_methods_test.cpp | 12 +++--- 11 files changed, 70 insertions(+), 78 deletions(-) diff --git a/source/source_relax/lattice_change_basic.cpp b/source/source_relax/lattice_change_basic.cpp index ccbba4d310c..7f0b4a26124 100644 --- a/source/source_relax/lattice_change_basic.cpp +++ b/source/source_relax/lattice_change_basic.cpp @@ -343,36 +343,32 @@ void Lattice_Change_Basic::terminate(const bool converged, std::ofstream& ofs) return; } -void Lattice_Change_Basic::setup_etot(const double &energy_in, const bool judgement) +void Lattice_Change_Basic::setup_etot(const double &energy_in, const bool judgement, std::vector& etot_info) { + // etot_info[0] = etot (current total energy) + // etot_info[1] = etot_p (previous total energy) + // ediff = etot_info[0] - etot_info[1] (computed on demand) + if (Lattice_Change_Basic::stress_step == 1) { // p == previous - Lattice_Change_Basic::etot_p = energy_in; - Lattice_Change_Basic::etot = energy_in; - ediff = etot - etot_p; + etot_info[1] = energy_in; + etot_info[0] = energy_in; } else { if (judgement) { - Lattice_Change_Basic::etot = energy_in; - if (Lattice_Change_Basic::etot_p > etot) - { - ediff = etot - etot_p; - Lattice_Change_Basic::etot_p = etot; - } - else + etot_info[0] = energy_in; + if (etot_info[1] > etot_info[0]) { - // this step will not be accepted - ediff = 0.0; + etot_info[1] = etot_info[0]; } } else // for bfgs { - Lattice_Change_Basic::etot_p = etot; - Lattice_Change_Basic::etot = energy_in; - ediff = etot - etot_p; + etot_info[1] = etot_info[0]; + etot_info[0] = energy_in; } } diff --git a/source/source_relax/lattice_change_basic.h b/source/source_relax/lattice_change_basic.h index 5a75277eb38..e3d92162627 100644 --- a/source/source_relax/lattice_change_basic.h +++ b/source/source_relax/lattice_change_basic.h @@ -2,6 +2,7 @@ #define LATTICE_CHANGE_BASIC_H #include +#include #include "relax_data.h" #include "source_base/matrix.h" #include "source_cell/unitcell.h" @@ -9,20 +10,17 @@ /** * @namespace Lattice_Change_Basic * @brief Basic utilities and shared state for lattice relaxation algorithms. - * + * * This namespace provides common functions and parameters used by lattice * optimization methods. It shares core state variables through references to * Relax_Data, ensuring consistent data across different optimization algorithms. + * */ namespace Lattice_Change_Basic { // Shared state variables (referenced from Relax_Data for unified data sharing) static int& dim = Relax_Data::dim_lattice; ///< Dimension of free variables (9 for full lattice) static double& largest_grad = Relax_Data::largest_grad; ///< Largest gradient component -static int& istep = Relax_Data::istep; ///< Current ionic step index -static double& ediff = Relax_Data::ediff; ///< Energy difference from previous step -static double& etot = Relax_Data::etot; ///< Total energy of current step -static double& etot_p = Relax_Data::etot_p; ///< Total energy of previous step // Lattice-specific parameters (not shared with ion movement) extern int update_iter; ///< Number of successfully updated iterations @@ -68,7 +66,8 @@ void terminate(const bool converged, std::ofstream& ofs); * @brief Update energy values and compute energy difference. * @param energy_in Input energy value * @param judgement Flag for SD method (true) or BFGS (false) + * @param etot_info Vector containing [etot, etot_p] */ -void setup_etot(const double &energy_in, const bool judgement); +void setup_etot(const double &energy_in, const bool judgement, std::vector& etot_info); } // namespace Lattice_Change_Basic -#endif \ No newline at end of file +#endif diff --git a/source/source_relax/lattice_change_cg.cpp b/source/source_relax/lattice_change_cg.cpp index 1edc2d7fe37..2001ca0da51 100644 --- a/source/source_relax/lattice_change_cg.cpp +++ b/source/source_relax/lattice_change_cg.cpp @@ -24,7 +24,7 @@ void Lattice_Change_CG::allocate(void) this->e0 = 0.0; } -bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs) +bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs, std::vector& etot_info) { ModuleBase::TITLE("Lattice_Change_CG", "start"); @@ -77,7 +77,7 @@ bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ ModuleBase::matrix stress(stress_in); Lattice_Change_Basic::setup_gradient(ucell, lat.data(), grad.data(), stress); - Lattice_Change_Basic::setup_etot(etot_in, 0); + Lattice_Change_Basic::setup_etot(etot_in, 0, etot_info); bool converged = false; if (flag == 0) diff --git a/source/source_relax/lattice_change_cg.h b/source/source_relax/lattice_change_cg.h index 07f77b618d9..55ff2027b70 100644 --- a/source/source_relax/lattice_change_cg.h +++ b/source/source_relax/lattice_change_cg.h @@ -15,7 +15,7 @@ class Lattice_Change_CG : public CG_Base ~Lattice_Change_CG() = default; void allocate(void); - bool start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot, std::ofstream& ofs); + bool start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot, std::ofstream& ofs, std::vector& etot_info); private: std::vector lat0; diff --git a/source/source_relax/lattice_change_methods.cpp b/source/source_relax/lattice_change_methods.cpp index 0fff33ba8f9..21a7e4b9509 100644 --- a/source/source_relax/lattice_change_methods.cpp +++ b/source/source_relax/lattice_change_methods.cpp @@ -25,10 +25,9 @@ void Lattice_Change_Methods::cal_lattice_change(const int &istep, std::ofstream& ofs) { ModuleBase::TITLE("Lattice_Change_Methods", "lattice_change_init"); - Lattice_Change_Basic::istep = istep; Lattice_Change_Basic::stress_step = stress_step; - converged_ = lccg.start(ucell, stress, etot, ofs); + converged_ = lccg.start(ucell, stress, etot, ofs, etot_info_); return; } diff --git a/source/source_relax/lattice_change_methods.h b/source/source_relax/lattice_change_methods.h index 6aad18c6833..86f0d756a19 100644 --- a/source/source_relax/lattice_change_methods.h +++ b/source/source_relax/lattice_change_methods.h @@ -2,6 +2,7 @@ #define LATTICE_CHANGE_METHODS_H #include +#include #include "lattice_change_basic.h" #include "lattice_change_cg.h" @@ -28,7 +29,7 @@ class Lattice_Change_Methods double get_ediff(void) const { - return Lattice_Change_Basic::ediff; + return etot_info_[0] - etot_info_[1]; } double get_largest_grad(void) const @@ -39,5 +40,6 @@ class Lattice_Change_Methods private: Lattice_Change_CG lccg; bool converged_ = false; + std::vector etot_info_{0.0, 0.0}; // [etot, etot_p] }; #endif diff --git a/source/source_relax/relax_data.cpp b/source/source_relax/relax_data.cpp index c464267bec6..bddffb81e02 100644 --- a/source/source_relax/relax_data.cpp +++ b/source/source_relax/relax_data.cpp @@ -4,10 +4,6 @@ int Relax_Data::dim = 0; int Relax_Data::dim_lattice = 0; double Relax_Data::largest_grad = 0.0; -int Relax_Data::istep = 0; -double Relax_Data::ediff = 0.0; -double Relax_Data::etot = 0.0; -double Relax_Data::etot_p = 0.0; void Relax_Data::allocate(const int dim_in) { pos.resize(dim_in, 0.0); diff --git a/source/source_relax/relax_data.h b/source/source_relax/relax_data.h index c5f2f5bf114..ec8ed2b1f52 100644 --- a/source/source_relax/relax_data.h +++ b/source/source_relax/relax_data.h @@ -32,12 +32,8 @@ class Relax_Data { // Static members - shared global state across all relaxation instances static int dim; ///< Dimension of free variables (3 * number of atoms) for ion movement static int dim_lattice; ///< Dimension of free variables (9) for lattice change - + static double largest_grad; ///< Largest gradient component (force) in current step - static int istep; ///< Current iteration step index - static double ediff; ///< Energy difference from previous step (etot - etot_p) - static double etot; ///< Total energy of current step - static double etot_p; ///< Total energy of previous step // Instance members - per-iteration data std::vector pos; ///< Current atomic positions in Bohr diff --git a/source/source_relax/test/lattice_change_basic_test.cpp b/source/source_relax/test/lattice_change_basic_test.cpp index 35fd638c623..d9ddb0ffccf 100644 --- a/source/source_relax/test/lattice_change_basic_test.cpp +++ b/source/source_relax/test/lattice_change_basic_test.cpp @@ -479,50 +479,54 @@ TEST_F(LatticeChangeBasicTest, SetupEtotStressStep1) { Lattice_Change_Basic::stress_step = 1; double energy_in = 100.0; + std::vector etot_info(2, 0.0); - Lattice_Change_Basic::setup_etot(energy_in, true); + Lattice_Change_Basic::setup_etot(energy_in, true, etot_info); - EXPECT_DOUBLE_EQ(energy_in, Lattice_Change_Basic::etot_p); - EXPECT_DOUBLE_EQ(energy_in, Lattice_Change_Basic::etot); - EXPECT_DOUBLE_EQ(0.0, Lattice_Change_Basic::ediff); + EXPECT_DOUBLE_EQ(energy_in, etot_info[1]); + EXPECT_DOUBLE_EQ(energy_in, etot_info[0]); + EXPECT_DOUBLE_EQ(0.0, etot_info[0] - etot_info[1]); } TEST_F(LatticeChangeBasicTest, SetupEtotJudgementTrueHigherEnergy) { Lattice_Change_Basic::stress_step = 2; double energy_in = 90.0; - Lattice_Change_Basic::etot_p = 100.0; + std::vector etot_info = {0.0, 100.0}; - Lattice_Change_Basic::setup_etot(energy_in, true); + Lattice_Change_Basic::setup_etot(energy_in, true, etot_info); - EXPECT_DOUBLE_EQ(90.0, Lattice_Change_Basic::etot); - EXPECT_DOUBLE_EQ(-10.0, Lattice_Change_Basic::ediff); + // When judgement=true and etot_p > etot, etot_p is updated to etot + EXPECT_DOUBLE_EQ(90.0, etot_info[0]); + EXPECT_DOUBLE_EQ(90.0, etot_info[1]); + EXPECT_DOUBLE_EQ(0.0, etot_info[0] - etot_info[1]); } TEST_F(LatticeChangeBasicTest, SetupEtotJudgementTrueLowerEnergy) { Lattice_Change_Basic::stress_step = 2; double energy_in = 100.0; - Lattice_Change_Basic::etot_p = 90.0; + std::vector etot_info = {0.0, 90.0}; - Lattice_Change_Basic::setup_etot(energy_in, true); + Lattice_Change_Basic::setup_etot(energy_in, true, etot_info); - EXPECT_DOUBLE_EQ(100.0, Lattice_Change_Basic::etot); - EXPECT_DOUBLE_EQ(0.0, Lattice_Change_Basic::ediff); + // When judgement=true and etot_p <= etot, etot_p is not updated + EXPECT_DOUBLE_EQ(100.0, etot_info[0]); + EXPECT_DOUBLE_EQ(90.0, etot_info[1]); + EXPECT_DOUBLE_EQ(10.0, etot_info[0] - etot_info[1]); } TEST_F(LatticeChangeBasicTest, SetupEtotJudgementFalse) { Lattice_Change_Basic::stress_step = 2; double energy_in = 80.0; - Lattice_Change_Basic::etot_p = 90.0; - Lattice_Change_Basic::etot = 100.0; + std::vector etot_info = {100.0, 90.0}; - Lattice_Change_Basic::setup_etot(energy_in, false); + Lattice_Change_Basic::setup_etot(energy_in, false, etot_info); - EXPECT_DOUBLE_EQ(100.0, Lattice_Change_Basic::etot_p); - EXPECT_DOUBLE_EQ(80.0, Lattice_Change_Basic::etot); - EXPECT_DOUBLE_EQ(-20.0, Lattice_Change_Basic::ediff); + EXPECT_DOUBLE_EQ(100.0, etot_info[1]); + EXPECT_DOUBLE_EQ(80.0, etot_info[0]); + EXPECT_DOUBLE_EQ(-20.0, etot_info[0] - etot_info[1]); } // ============================================================================ diff --git a/source/source_relax/test/lattice_change_cg_test.cpp b/source/source_relax/test/lattice_change_cg_test.cpp index ce41702614f..084dcc75099 100644 --- a/source/source_relax/test/lattice_change_cg_test.cpp +++ b/source/source_relax/test/lattice_change_cg_test.cpp @@ -20,6 +20,7 @@ class LatticeChangeCGTest : public ::testing::Test Lattice_Change_Basic::stress_step = 1; Lattice_Change_Basic::update_iter = 5; lc_cg.allocate(); + etot_info.resize(2, 0.0); } void TearDown() override @@ -28,6 +29,7 @@ class LatticeChangeCGTest : public ::testing::Test } Lattice_Change_CG lc_cg; + std::vector etot_info; }; // Test whether the allocate() function can correctly allocate memory space @@ -76,7 +78,7 @@ TEST_F(LatticeChangeCGTest, TestStartConverged) // call function std::ofstream ofs("test_lc_cg_start_converged.log"); - lc_cg.start(ucell, stress, etot, ofs); + lc_cg.start(ucell, stress, etot, ofs, etot_info); ofs.close(); // Check output @@ -105,7 +107,7 @@ TEST_F(LatticeChangeCGTest, TestStartSd) // call function std::ofstream ofs("test_lc_cg_start_sd.log"); - lc_cg.start(ucell, stress, etot, ofs); + lc_cg.start(ucell, stress, etot, ofs, etot_info); ofs.close(); // Check output @@ -134,13 +136,13 @@ TEST_F(LatticeChangeCGTest, TestStartTrialGoto) // call function lc_cg.move0[0] = 1.0; std::ofstream ofs1("test_lc_cg_start_trial_goto_temp1.log"); - lc_cg.start(ucell, stress, etot, ofs1); + lc_cg.start(ucell, stress, etot, ofs1, etot_info); ofs1.close(); std::remove("test_lc_cg_start_trial_goto_temp1.log"); Lattice_Change_Basic::stress_step = 2; lc_cg.move0[0] = 10.0; std::ofstream ofs("test_lc_cg_start_trial_goto.log"); - lc_cg.start(ucell, stress, etot, ofs); + lc_cg.start(ucell, stress, etot, ofs, etot_info); ofs.close(); // Check output @@ -168,12 +170,12 @@ TEST_F(LatticeChangeCGTest, TestStartTrial) // call function std::ofstream ofs1("test_lc_cg_start_trial_temp1.log"); - lc_cg.start(ucell, stress, etot, ofs1); + lc_cg.start(ucell, stress, etot, ofs1, etot_info); ofs1.close(); std::remove("test_lc_cg_start_trial_temp1.log"); Lattice_Change_Basic::stress_step = 2; std::ofstream ofs("test_lc_cg_start_trial.log"); - lc_cg.start(ucell, stress, etot, ofs); + lc_cg.start(ucell, stress, etot, ofs, etot_info); ofs.close(); // Check output @@ -201,16 +203,16 @@ TEST_F(LatticeChangeCGTest, TestStartNoTrialGotoCase1) // call function std::ofstream ofs1("test_lc_cg_start_notrial_goto_case1_temp1.log"); - lc_cg.start(ucell, stress, etot, ofs1); + lc_cg.start(ucell, stress, etot, ofs1, etot_info); ofs1.close(); std::remove("test_lc_cg_start_notrial_goto_case1_temp1.log"); Lattice_Change_Basic::stress_step = 2; std::ofstream ofs2("test_lc_cg_start_notrial_goto_case1_temp2.log"); - lc_cg.start(ucell, stress, etot, ofs2); + lc_cg.start(ucell, stress, etot, ofs2, etot_info); ofs2.close(); std::remove("test_lc_cg_start_notrial_goto_case1_temp2.log"); std::ofstream ofs("test_lc_cg_start_notrial_goto_case1.log"); - lc_cg.start(ucell, stress, etot, ofs); + lc_cg.start(ucell, stress, etot, ofs, etot_info); ofs.close(); // Check output @@ -239,18 +241,18 @@ TEST_F(LatticeChangeCGTest, TestStartNoTrialGotoCase2) // call function lc_cg.move0[0] = 0.1; std::ofstream ofs1("test_lc_cg_start_notrial_goto_case2_temp1.log"); - lc_cg.start(ucell, stress, etot, ofs1); + lc_cg.start(ucell, stress, etot, ofs1, etot_info); ofs1.close(); std::remove("test_lc_cg_start_notrial_goto_case2_temp1.log"); Lattice_Change_Basic::stress_step = 2; std::ofstream ofs2("test_lc_cg_start_notrial_goto_case2_temp2.log"); - lc_cg.start(ucell, stress, etot, ofs2); + lc_cg.start(ucell, stress, etot, ofs2, etot_info); ofs2.close(); std::remove("test_lc_cg_start_notrial_goto_case2_temp2.log"); std::ofstream ofs("test_lc_cg_start_notrial_goto_case2.log"); lc_cg.move0[0] = 0.1; stress(0, 1) = 0.0001; - lc_cg.start(ucell, stress, etot, ofs); + lc_cg.start(ucell, stress, etot, ofs, etot_info); ofs.close(); // Check output @@ -279,17 +281,17 @@ TEST_F(LatticeChangeCGTest, TestStartNoTrial) // call function lc_cg.move0[0] = 1.0; std::ofstream ofs1("test_lc_cg_start_notrial_temp1.log"); - lc_cg.start(ucell, stress, etot, ofs1); + lc_cg.start(ucell, stress, etot, ofs1, etot_info); ofs1.close(); std::remove("test_lc_cg_start_notrial_temp1.log"); Lattice_Change_Basic::stress_step = 2; lc_cg.move0[0] = 10.0; std::ofstream ofs2("test_lc_cg_start_notrial_temp2.log"); - lc_cg.start(ucell, stress, etot, ofs2); + lc_cg.start(ucell, stress, etot, ofs2, etot_info); ofs2.close(); std::remove("test_lc_cg_start_notrial_temp2.log"); std::ofstream ofs("test_lc_cg_start_notrial.log"); - lc_cg.start(ucell, stress, etot, ofs); + lc_cg.start(ucell, stress, etot, ofs, etot_info); ofs.close(); // Check output diff --git a/source/source_relax/test/lattice_change_methods_test.cpp b/source/source_relax/test/lattice_change_methods_test.cpp index 8b78c7371d6..479497de095 100644 --- a/source/source_relax/test/lattice_change_methods_test.cpp +++ b/source/source_relax/test/lattice_change_methods_test.cpp @@ -25,7 +25,7 @@ void Lattice_Change_CG::allocate(void) { } -bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs) +bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs, std::vector& etot_info) { return false; } @@ -68,8 +68,7 @@ TEST_F(LatticeChangeMethodsTest, CalLatticeChange) lcm.cal_lattice_change(istep, stress_step, stress, etot, ucell, ofs); - // Assert that the static variables istep and stress_step are set correctly - EXPECT_EQ(Lattice_Change_Basic::istep, istep); + // Assert that the static variable stress_step is set correctly EXPECT_EQ(Lattice_Change_Basic::stress_step, stress_step); // Note: To fully test this function, we would also need to check the output of lccg.start(). @@ -85,10 +84,9 @@ TEST_F(LatticeChangeMethodsTest, GetConverged) // Test the get_ediff function TEST_F(LatticeChangeMethodsTest, GetEdiff) { - lcm.get_ediff(); - - // Assert that the static variable ediff is set to 0.0 - EXPECT_DOUBLE_EQ(Lattice_Change_Basic::ediff, 0.0); + // ediff is computed as etot_info[0] - etot_info[1] + // Initially both are 0.0, so ediff should be 0.0 + EXPECT_DOUBLE_EQ(lcm.get_ediff(), 0.0); } // Test the get_largest_grad function From 2bdca9c3cdec410f6b47f3407dc5a416b9824eb1 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 15 Jun 2026 13:15:14 +0800 Subject: [PATCH 46/50] update --- source/source_io/module_parameter/input_conv.cpp | 1 - source/source_io/test/for_testing_input_conv.h | 1 - source/source_relax/ions_move_basic.cpp | 1 - source/source_relax/ions_move_basic.h | 1 - source/source_relax/relax_driver.cpp | 2 +- 5 files changed, 1 insertion(+), 5 deletions(-) diff --git a/source/source_io/module_parameter/input_conv.cpp b/source/source_io/module_parameter/input_conv.cpp index 4cc2ac1a7f7..f27ba12f886 100644 --- a/source/source_io/module_parameter/input_conv.cpp +++ b/source/source_io/module_parameter/input_conv.cpp @@ -191,7 +191,6 @@ void Input_Conv::Convert() Ions_Move_Basic::relax_bfgs_rmax = PARAM.inp.relax_bfgs_rmax; Ions_Move_Basic::relax_bfgs_rmin = PARAM.inp.relax_bfgs_rmin; 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; Lattice_Change_Basic::fixed_axes = PARAM.inp.fixed_axes; diff --git a/source/source_io/test/for_testing_input_conv.h b/source/source_io/test/for_testing_input_conv.h index 9efdfc2c705..44f79b5b9bf 100644 --- a/source/source_io/test/for_testing_input_conv.h +++ b/source/source_io/test/for_testing_input_conv.h @@ -91,7 +91,6 @@ double BFGS_Basic::relax_bfgs_w2 = -1.0; double Ions_Move_Basic::relax_bfgs_rmax = -1.0; double Ions_Move_Basic::relax_bfgs_rmin = -1.0; double Ions_Move_Basic::relax_bfgs_init = -1.0; -int Ions_Move_Basic::out_stru = 0; double Ions_Move_CG::RELAX_CG_THR = -1.0; std::string Lattice_Change_Basic::fixed_axes = "None"; int ModuleSymmetry::Symmetry::symm_flag = 0; diff --git a/source/source_relax/ions_move_basic.cpp b/source/source_relax/ions_move_basic.cpp index 40dd89683d2..8138c28cf71 100644 --- a/source/source_relax/ions_move_basic.cpp +++ b/source/source_relax/ions_move_basic.cpp @@ -14,7 +14,6 @@ double Ions_Move_Basic::relax_bfgs_rmax = -1.0; // default is 0.8 double Ions_Move_Basic::relax_bfgs_rmin = -1.0; // default is 1e-5 double Ions_Move_Basic::relax_bfgs_init = -1.0; // default is 0.5 double Ions_Move_Basic::best_xxx = 1.0; -int Ions_Move_Basic::out_stru = 0; std::vector Ions_Move_Basic::relax_method = {"bfgs","2"}; void Ions_Move_Basic::setup_gradient(const UnitCell &ucell, const ModuleBase::matrix &force, double *pos, double *grad, std::ofstream& ofs) diff --git a/source/source_relax/ions_move_basic.h b/source/source_relax/ions_move_basic.h index b9980229649..c0ccd9f3b39 100644 --- a/source/source_relax/ions_move_basic.h +++ b/source/source_relax/ions_move_basic.h @@ -29,7 +29,6 @@ extern double relax_bfgs_rmin; ///< Minimum trust radius (default: 1e-5 Bo extern double relax_bfgs_init; ///< Initial trust radius (default: 0.5 Bohr) extern double best_xxx; ///< Last step length from CG, used as BFGS initial guess extern std::vector relax_method; ///< Relaxation method settings -extern int out_stru; ///< Structure output flag /** * @brief Setup gradient from atomic forces. diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index f4d72173331..7a61af9ab02 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -176,7 +176,7 @@ void Relax_Driver::stru_out(const int istep, UnitCell& ucell, const Input_para& PARAM.globalv.deepks_setorb, GlobalV::MY_RANK); - if (Ions_Move_Basic::out_stru) + if (PARAM.inp.out_stru) { ss1 << PARAM.globalv.global_out_dir << "STRU_ION"; ss1 << istep << "_D"; From 4aec70c1f30f6210c09d2a39e7bc37620b2ecaf0 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 15 Jun 2026 14:56:53 +0800 Subject: [PATCH 47/50] remove relax_methods --- .../source_io/module_parameter/input_conv.cpp | 1 - source/source_relax/ions_move_basic.cpp | 1 - source/source_relax/ions_move_basic.h | 1 - source/source_relax/ions_move_cg.cpp | 8 +-- source/source_relax/ions_move_cg.h | 2 +- source/source_relax/ions_move_methods.cpp | 25 +++---- source/source_relax/ions_move_methods.h | 3 +- source/source_relax/relax_driver.cpp | 49 +++++++------ source/source_relax/relax_nsync.cpp | 3 +- .../source_relax/test/ions_move_cg_test.cpp | 71 ++++++++++++------- .../test/ions_move_methods_test.cpp | 26 +++---- 11 files changed, 105 insertions(+), 85 deletions(-) diff --git a/source/source_io/module_parameter/input_conv.cpp b/source/source_io/module_parameter/input_conv.cpp index f27ba12f886..46f8eed347f 100644 --- a/source/source_io/module_parameter/input_conv.cpp +++ b/source/source_io/module_parameter/input_conv.cpp @@ -191,7 +191,6 @@ void Input_Conv::Convert() Ions_Move_Basic::relax_bfgs_rmax = PARAM.inp.relax_bfgs_rmax; Ions_Move_Basic::relax_bfgs_rmin = PARAM.inp.relax_bfgs_rmin; Ions_Move_Basic::relax_bfgs_init = PARAM.inp.relax_bfgs_init; - Ions_Move_Basic::relax_method = PARAM.inp.relax_method; Lattice_Change_Basic::fixed_axes = PARAM.inp.fixed_axes; diff --git a/source/source_relax/ions_move_basic.cpp b/source/source_relax/ions_move_basic.cpp index 8138c28cf71..443570403c6 100644 --- a/source/source_relax/ions_move_basic.cpp +++ b/source/source_relax/ions_move_basic.cpp @@ -14,7 +14,6 @@ double Ions_Move_Basic::relax_bfgs_rmax = -1.0; // default is 0.8 double Ions_Move_Basic::relax_bfgs_rmin = -1.0; // default is 1e-5 double Ions_Move_Basic::relax_bfgs_init = -1.0; // default is 0.5 double Ions_Move_Basic::best_xxx = 1.0; -std::vector Ions_Move_Basic::relax_method = {"bfgs","2"}; void Ions_Move_Basic::setup_gradient(const UnitCell &ucell, const ModuleBase::matrix &force, double *pos, double *grad, std::ofstream& ofs) { diff --git a/source/source_relax/ions_move_basic.h b/source/source_relax/ions_move_basic.h index c0ccd9f3b39..482e3559e5e 100644 --- a/source/source_relax/ions_move_basic.h +++ b/source/source_relax/ions_move_basic.h @@ -28,7 +28,6 @@ extern double relax_bfgs_rmax; ///< Maximum trust radius (default: 0.8 Boh extern double relax_bfgs_rmin; ///< Minimum trust radius (default: 1e-5 Bohr) extern double relax_bfgs_init; ///< Initial trust radius (default: 0.5 Bohr) extern double best_xxx; ///< Last step length from CG, used as BFGS initial guess -extern std::vector relax_method; ///< Relaxation method settings /** * @brief Setup gradient from atomic forces. diff --git a/source/source_relax/ions_move_cg.cpp b/source/source_relax/ions_move_cg.cpp index 9c3a576b57d..98334aa5d44 100644 --- a/source/source_relax/ions_move_cg.cpp +++ b/source/source_relax/ions_move_cg.cpp @@ -23,7 +23,7 @@ void Ions_Move_CG::allocate(const int dim) this->e0 = 0.0; } -bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info) +bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info, std::vector& relax_method) { ModuleBase::TITLE("Ions_Move_CG", "start"); assert(Ions_Move_Basic::dim > 0); @@ -106,13 +106,13 @@ bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const fmax = fa; sd = false; - if (Ions_Move_Basic::relax_method[0] == "cg_bfgs") + if (relax_method[0] == "cg_bfgs") { if (Ions_Move_Basic::largest_grad * ModuleBase::Ry_to_eV / ModuleBase::BOHR_TO_A < RELAX_CG_THR) { - Ions_Move_Basic::relax_method[0] = "bfgs"; - Ions_Move_Basic::relax_method[1] = "1"; + relax_method[0] = "bfgs"; + relax_method[1] = "1"; } Ions_Move_Basic::best_xxx = steplength; } diff --git a/source/source_relax/ions_move_cg.h b/source/source_relax/ions_move_cg.h index 186cb4b1e03..b6d7020187e 100644 --- a/source/source_relax/ions_move_cg.h +++ b/source/source_relax/ions_move_cg.h @@ -15,7 +15,7 @@ class Ions_Move_CG : public CG_Base ~Ions_Move_CG() = default; void allocate(const int dim); - bool start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info); + bool start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info, std::vector& relax_method); static double RELAX_CG_THR; int sd_step = 0; diff --git a/source/source_relax/ions_move_methods.cpp b/source/source_relax/ions_move_methods.cpp index e1452721c7c..297cd4a3a96 100644 --- a/source/source_relax/ions_move_methods.cpp +++ b/source/source_relax/ions_move_methods.cpp @@ -58,36 +58,37 @@ void Ions_Move_Methods::cal_movement(const int &istep, const ModuleBase::matrix &f, const double &etot, UnitCell &ucell, - std::ofstream& ofs) + std::ofstream& ofs, + std::vector& relax_method) { ModuleBase::TITLE("Ions_Move_Methods", "init"); - if (Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] != "1") + if (relax_method[0] == "bfgs" && relax_method[1] != "1") { converged_ = bfgs.start(ucell, f, etot, force_step, update_iter_, ofs, etot_info_); } - else if (Ions_Move_Basic::relax_method[0] == "sd") + else if (relax_method[0] == "sd") { converged_ = sd.start(ucell, f, etot, force_step, update_iter_, ofs, etot_info_); } - else if (Ions_Move_Basic::relax_method[0] == "cg") + else if (relax_method[0] == "cg") { - converged_ = cg.start(ucell, f, etot, force_step, update_iter_, ofs, etot_info_); + converged_ = cg.start(ucell, f, etot, force_step, update_iter_, ofs, etot_info_, relax_method); } - else if (Ions_Move_Basic::relax_method[0] == "cg_bfgs") + else if (relax_method[0] == "cg_bfgs") { - converged_ = cg.start(ucell, f, etot, force_step, update_iter_, ofs, etot_info_); + converged_ = cg.start(ucell, f, etot, force_step, update_iter_, ofs, etot_info_, relax_method); } - else if(Ions_Move_Basic::relax_method[0] == "bfgs"&&Ions_Move_Basic::relax_method[1] == "1") + else if (relax_method[0] == "bfgs" && relax_method[1] == "1") { - converged_ = bfgs_trad.relax_step(f,ucell, ofs); + converged_ = bfgs_trad.relax_step(f, ucell, ofs); } - else if(Ions_Move_Basic::relax_method[0] == "lbfgs") + else if (relax_method[0] == "lbfgs") { - converged_ = lbfgs.relax_step(f,ucell,etot, ofs); + converged_ = lbfgs.relax_step(f, ucell, etot, ofs); } else { - ModuleBase::WARNING("Ions_Move_Methods::init", "the parameter Ions_Move_Basic::relax_method is not correct."); + ModuleBase::WARNING("Ions_Move_Methods::init", "the parameter relax_method is not correct."); converged_ = false; } return; diff --git a/source/source_relax/ions_move_methods.h b/source/source_relax/ions_move_methods.h index 202372a395e..0738218df68 100644 --- a/source/source_relax/ions_move_methods.h +++ b/source/source_relax/ions_move_methods.h @@ -23,7 +23,8 @@ class Ions_Move_Methods const ModuleBase::matrix &f, const double &etot, UnitCell &ucell, - std::ofstream& ofs); + std::ofstream& ofs, + std::vector& relax_method); bool get_converged() const { diff --git a/source/source_relax/relax_driver.cpp b/source/source_relax/relax_driver.cpp index 7a61af9ab02..26128bf0408 100644 --- a/source/source_relax/relax_driver.cpp +++ b/source/source_relax/relax_driver.cpp @@ -53,7 +53,7 @@ void Relax_Driver::relax_driver( ++steps[0]; } - this->final_out(steps[0]+1, ucell, inp); + this->final_out(steps[0], ucell, inp); ModuleBase::timer::end("Relax_Driver", "relax_driver"); return; @@ -147,7 +147,7 @@ bool Relax_Driver::relax_step(std::vector& steps, stress, steps[1], steps[2], ofs_running); } - this->stru_out(steps[0]+1, ucell, inp); + this->stru_out(steps[0], ucell, inp); ModuleIO::output_after_relax(converged, p_esolver->conv_esolver, ofs_running); @@ -176,26 +176,29 @@ void Relax_Driver::stru_out(const int istep, UnitCell& ucell, const Input_para& PARAM.globalv.deepks_setorb, GlobalV::MY_RANK); - if (PARAM.inp.out_stru) + if (inp.out_stru) { - ss1 << PARAM.globalv.global_out_dir << "STRU_ION"; - ss1 << istep << "_D"; - unitcell::print_stru_file(ucell, - ucell.atoms, - ucell.latvec, - ss1.str(), - inp.nspin, - true, - inp.calculation == "md", - inp.out_mul, - need_orb, - PARAM.globalv.deepks_setorb, - GlobalV::MY_RANK); - - ModuleIO::CifParser::write(PARAM.globalv.global_out_dir + "STRU_NOW.cif", - ucell, - "# Generated by ABACUS ModuleIO::CifParser", - "data_?"); + if (inp.out_freq_ion == 0 || istep % inp.out_freq_ion == 0) + { + ss1 << PARAM.globalv.global_out_dir << "STRU_ION"; + ss1 << istep+1 << "_D"; + unitcell::print_stru_file(ucell, + ucell.atoms, + ucell.latvec, + ss1.str(), + inp.nspin, + true, + inp.calculation == "md", + inp.out_mul, + need_orb, + PARAM.globalv.deepks_setorb, + GlobalV::MY_RANK); + + ModuleIO::CifParser::write(PARAM.globalv.global_out_dir + "STRU_NOW.cif", + ucell, + "# Generated by ABACUS ModuleIO::CifParser", + "data_?"); + } } } @@ -222,7 +225,7 @@ void Relax_Driver::final_out(const int istep, UnitCell& ucell, const Input_para& "# Generated by ABACUS ModuleIO::CifParser", "data_?"); - if (istep - 1 == inp.relax_nmax) + if (istep == inp.relax_nmax) { std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; std::cout << " Geometry relaxation stops here due to reaching the maximum " << std::endl; @@ -232,7 +235,7 @@ void Relax_Driver::final_out(const int istep, UnitCell& ucell, const Input_para& else { std::cout << "\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; - std::cout << " Geometry relaxation thresholds are reached within " << istep - 1 << " steps." << std::endl; + std::cout << " Geometry relaxation thresholds are reached within " << istep << " steps." << std::endl; std::cout << " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; } diff --git a/source/source_relax/relax_nsync.cpp b/source/source_relax/relax_nsync.cpp index 14e900b1fb1..7134cb6567a 100644 --- a/source/source_relax/relax_nsync.cpp +++ b/source/source_relax/relax_nsync.cpp @@ -90,7 +90,8 @@ bool IonCellOptimizer::relax_step(const int& istep, assert(PARAM.inp.cal_force == 1); // Calculate and apply atomic movement - IMM.cal_movement(istep, force_step, force, energy, ucell, ofs_running); + std::vector relax_method = PARAM.inp.relax_method; + IMM.cal_movement(istep, force_step, force, energy, ucell, ofs_running, relax_method); ++force_step; // Check convergence diff --git a/source/source_relax/test/ions_move_cg_test.cpp b/source/source_relax/test/ions_move_cg_test.cpp index b86c70254e3..e06b5758db6 100644 --- a/source/source_relax/test/ions_move_cg_test.cpp +++ b/source/source_relax/test/ions_move_cg_test.cpp @@ -98,10 +98,11 @@ TEST_F(IonsMoveCGTest, TestStartConverged) ModuleBase::matrix force(2, 3); double etot = 0.0; std::vector etot_info(2, 0.0); + std::vector relax_method = {"cg", "1"}; // call function std::ofstream ofs("TestStartConverged.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs, etot_info); + im_cg.start(ucell, force, etot, istep, update_iter, ofs, etot_info, relax_method); ofs.close(); // Check output @@ -127,7 +128,7 @@ TEST_F(IonsMoveCGTest, TestStartSd) { // setup data const int istep = 1; - Ions_Move_Basic::relax_method[0] = "cg_bfgs"; + std::vector relax_method = {"cg_bfgs", "1"}; Ions_Move_CG::RELAX_CG_THR = 100.0; UnitCell ucell; setupucell(ucell); @@ -138,7 +139,7 @@ TEST_F(IonsMoveCGTest, TestStartSd) // call function std::ofstream ofs("TestStartSd.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs, etot_info); + im_cg.start(ucell, force, etot, istep, update_iter, ofs, etot_info, relax_method); ofs.close(); // Check output @@ -151,7 +152,7 @@ TEST_F(IonsMoveCGTest, TestStartSd) EXPECT_THAT(output, testing::HasSubstr(expected_output)); EXPECT_EQ(update_iter, 5); - EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); + EXPECT_EQ(relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.01); EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); EXPECT_DOUBLE_EQ(Ions_Move_Basic::relax_bfgs_init, 1.0); @@ -162,24 +163,27 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) { // setup data const int istep = 1; + Ions_Move_CG::RELAX_CG_THR = 100.0; UnitCell ucell; setupucell(ucell); ModuleBase::matrix force(2, 3); force(0, 0) = 0.1; double etot = 0.0; std::vector etot_info(2, 0.0); + std::vector relax_method = {"cg_bfgs", "1"}; // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartTrialGoto_temp1.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info, relax_method); ofs1.close(); std::remove("TestStartTrialGoto_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 10.0; force(0, 0) = 0.001; + relax_method = {"cg_bfgs", "1"}; std::ofstream ofs("TestStartTrialGoto.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info, relax_method); ofs.close(); // Check output @@ -192,9 +196,9 @@ TEST_F(IonsMoveCGTest, TestStartTrialGoto) EXPECT_THAT(output, testing::HasSubstr(expected_output)); EXPECT_EQ(update_iter, 5); - EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); + EXPECT_EQ(relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.001); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); + EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, 10.0); EXPECT_DOUBLE_EQ(Ions_Move_Basic::relax_bfgs_init, 10.0); } @@ -209,17 +213,18 @@ TEST_F(IonsMoveCGTest, TestStartTrial) force(0, 0) = 0.01; double etot = 0.0; std::vector etot_info(2, 0.0); + std::vector relax_method = {"cg_bfgs", "1"}; // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartTrial_temp1.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info, relax_method); ofs1.close(); std::remove("TestStartTrial_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 10.0; std::ofstream ofs("TestStartTrial.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info, relax_method); ofs.close(); // Check output @@ -232,9 +237,9 @@ TEST_F(IonsMoveCGTest, TestStartTrial) EXPECT_THAT(output, testing::HasSubstr(expected_output)); EXPECT_EQ(update_iter, 5); - EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); + EXPECT_EQ(relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.01); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); + EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, 10.0); EXPECT_DOUBLE_EQ(Ions_Move_Basic::relax_bfgs_init, 70.0); } @@ -243,28 +248,31 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) { // setup data const int istep = 1; + Ions_Move_CG::RELAX_CG_THR = 100.0; UnitCell ucell; setupucell(ucell); ModuleBase::matrix force(2, 3); force(0, 0) = 0.1; double etot = 0.0; std::vector etot_info(2, 0.0); + std::vector relax_method = {"cg_bfgs", "1"}; // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrialGotoCase1_temp1.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info, relax_method); ofs1.close(); std::remove("TestStartNoTrialGotoCase1_temp1.log"); int istep_2 = 2; std::ofstream ofs2("TestStartNoTrialGotoCase1_temp2.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2, etot_info); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2, etot_info, relax_method); ofs2.close(); std::remove("TestStartNoTrialGotoCase1_temp2.log"); im_cg.move0[0] = 1.0; force(0, 0) = 0.001; + relax_method = {"cg_bfgs", "1"}; std::ofstream ofs("TestStartNoTrialGotoCase1.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info, relax_method); ofs.close(); // Check output @@ -277,9 +285,9 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase1) EXPECT_THAT(output, testing::HasSubstr(expected_output)); EXPECT_EQ(update_iter, 5); - EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); + EXPECT_EQ(relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.001); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); + EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, 490.0); EXPECT_DOUBLE_EQ(Ions_Move_Basic::relax_bfgs_init, 490.0); } @@ -288,27 +296,32 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) { // setup data const int istep = 1; + Ions_Move_CG::RELAX_CG_THR = 100.0; UnitCell ucell; setupucell(ucell); ModuleBase::matrix force(2, 3); force(0, 0) = 0.01; double etot = 0.0; std::vector etot_info(2, 0.0); + std::vector relax_method = {"cg_bfgs", "1"}; + Ions_Move_Basic::best_xxx = 1.0; + Ions_Move_Basic::relax_bfgs_init = 1.0; // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrialGotoCase2_temp1.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info, relax_method); ofs1.close(); std::remove("TestStartNoTrialGotoCase2_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 10.0; std::ofstream ofs2("TestStartNoTrialGotoCase2_temp2.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2, etot_info); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2, etot_info, relax_method); ofs2.close(); std::remove("TestStartNoTrialGotoCase2_temp2.log"); + relax_method = {"cg_bfgs", "1"}; std::ofstream ofs("TestStartNoTrialGotoCase2.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info, relax_method); ofs.close(); // Check output @@ -321,9 +334,9 @@ TEST_F(IonsMoveCGTest, TestStartNoTrialGotoCase2) EXPECT_THAT(output, testing::HasSubstr(expected_output)); EXPECT_EQ(update_iter, 5); - EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); + EXPECT_EQ(relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.01); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); + EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, 70.0); EXPECT_DOUBLE_EQ(Ions_Move_Basic::relax_bfgs_init, 70.0); } @@ -332,28 +345,32 @@ TEST_F(IonsMoveCGTest, TestStartNoTrial) { // setup data const int istep = 1; + Ions_Move_CG::RELAX_CG_THR = 100.0; UnitCell ucell; setupucell(ucell); ModuleBase::matrix force(2, 3); force(0, 0) = 0.01; double etot = 0.0; std::vector etot_info(2, 0.0); + std::vector relax_method = {"cg_bfgs", "1"}; + Ions_Move_Basic::best_xxx = 1.0; + Ions_Move_Basic::relax_bfgs_init = 1.0; // call function im_cg.move0[0] = 1.0; std::ofstream ofs1("TestStartNoTrial_temp1.log"); - im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info); + im_cg.start(ucell, force, etot, istep, update_iter, ofs1, etot_info, relax_method); ofs1.close(); std::remove("TestStartNoTrial_temp1.log"); int istep_2 = 2; im_cg.move0[0] = 1.0; force(0, 0) = 0.001; std::ofstream ofs2("TestStartNoTrial_temp2.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2, etot_info); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs2, etot_info, relax_method); ofs2.close(); std::remove("TestStartNoTrial_temp2.log"); std::ofstream ofs("TestStartNoTrial.log"); - im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info); + im_cg.start(ucell, force, etot, istep_2, update_iter, ofs, etot_info, relax_method); ofs.close(); // Check output @@ -366,9 +383,9 @@ TEST_F(IonsMoveCGTest, TestStartNoTrial) EXPECT_THAT(output, testing::HasSubstr(expected_output)); EXPECT_EQ(update_iter, 5); - EXPECT_EQ(Ions_Move_Basic::relax_method[0], "bfgs"); + EXPECT_EQ(relax_method[0], "bfgs"); EXPECT_DOUBLE_EQ(Ions_Move_Basic::largest_grad, 0.001); - EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, -1.0); + EXPECT_DOUBLE_EQ(Ions_Move_Basic::best_xxx, 1.0); EXPECT_NEAR(Ions_Move_Basic::relax_bfgs_init, 1.2345679012345678, 1e-12); } diff --git a/source/source_relax/test/ions_move_methods_test.cpp b/source/source_relax/test/ions_move_methods_test.cpp index 13f4d8432a5..514a2cb8008 100644 --- a/source/source_relax/test/ions_move_methods_test.cpp +++ b/source/source_relax/test/ions_move_methods_test.cpp @@ -135,22 +135,23 @@ TEST_F(IonsMoveMethodsTest, CalMovement) UnitCell ucell; std::ofstream ofs; - Ions_Move_Basic::relax_method[0] = "bfgs"; - Ions_Move_Basic::relax_method[1] = "1"; + std::vector relax_method; + + relax_method = {"bfgs", "1"}; imm.allocate(natom, "bfgs", "1"); - imm.cal_movement(istep, force_step, f, etot, ucell, ofs); + imm.cal_movement(istep, force_step, f, etot, ucell, ofs, relax_method); - Ions_Move_Basic::relax_method[0] = "sd"; + relax_method = {"sd", "1"}; imm.allocate(natom, "sd", "1"); - imm.cal_movement(istep, force_step, f, etot, ucell, ofs); + imm.cal_movement(istep, force_step, f, etot, ucell, ofs, relax_method); - Ions_Move_Basic::relax_method[0] = "cg"; + relax_method = {"cg", "1"}; imm.allocate(natom, "cg", "1"); - imm.cal_movement(istep, force_step, f, etot, ucell, ofs); + imm.cal_movement(istep, force_step, f, etot, ucell, ofs, relax_method); - Ions_Move_Basic::relax_method[0] = "cg_bfgs"; + relax_method = {"cg_bfgs", "1"}; imm.allocate(natom, "cg_bfgs", "1"); - imm.cal_movement(istep, force_step, f, etot, ucell, ofs); + imm.cal_movement(istep, force_step, f, etot, ucell, ofs, relax_method); } // Test the cal_movement() function warning quit @@ -162,17 +163,16 @@ TEST_F(IonsMoveMethodsTest, CalMovementWarningQuit) const double etot = 0.0; UnitCell ucell; std::ofstream ofs; - Ions_Move_Basic::relax_method[0] = "none"; - Ions_Move_Basic::relax_method[1] = "1"; + std::vector relax_method = {"none", "1"}; imm.allocate(natom, "none", "1"); GlobalV::ofs_warning.open("log"); - imm.cal_movement(istep, force_step, f, etot, ucell, ofs); + imm.cal_movement(istep, force_step, f, etot, ucell, ofs, relax_method); GlobalV::ofs_warning.close(); std::ifstream ifs("log"); std::string output((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); - EXPECT_THAT(output, testing::HasSubstr("the parameter Ions_Move_Basic::relax_method is not correct.")); + EXPECT_THAT(output, testing::HasSubstr("the parameter relax_method is not correct.")); ifs.close(); std::remove("log"); } From 004d99c0b31ccaeec1b6d1dfe2c4cdbaaaee5f1f Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 15 Jun 2026 14:59:18 +0800 Subject: [PATCH 48/50] delete useless variables --- source/source_relax/ions_move_cg.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/source_relax/ions_move_cg.h b/source/source_relax/ions_move_cg.h index b6d7020187e..7e45491332d 100644 --- a/source/source_relax/ions_move_cg.h +++ b/source/source_relax/ions_move_cg.h @@ -18,8 +18,6 @@ class Ions_Move_CG : public CG_Base bool start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info, std::vector& relax_method); static double RELAX_CG_THR; - int sd_step = 0; - int cg_step = 0; private: std::vector pos0; From 4d23722d1c3f1085f9779f93f47e7e08b5a603f9 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 15 Jun 2026 16:32:03 +0800 Subject: [PATCH 49/50] update move_cg method --- source/source_relax/ions_move_cg.cpp | 134 +++++++++++++-------------- source/source_relax/ions_move_cg.h | 14 +++ 2 files changed, 81 insertions(+), 67 deletions(-) diff --git a/source/source_relax/ions_move_cg.cpp b/source/source_relax/ions_move_cg.cpp index 98334aa5d44..8c7c23d10df 100644 --- a/source/source_relax/ions_move_cg.cpp +++ b/source/source_relax/ions_move_cg.cpp @@ -21,6 +21,20 @@ void Ions_Move_CG::allocate(const int dim) this->cg_grad0.resize(dim, 0.0); this->move0.resize(dim, 0.0); this->e0 = 0.0; + + this->sd = false; + this->trial = false; + this->ncggrad = 0; + this->nbrent = 0; + this->fa = 0.0; + this->fb = 0.0; + this->fc = 0.0; + this->xa = 0.0; + this->xb = 0.0; + this->xc = 0.0; + this->xpt = 0.0; + this->steplength = 0.0; + this->fmax = 0.0; } bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const double &etot_in, const int istep, int& update_iter, std::ofstream& ofs, std::vector& etot_info, std::vector& relax_method) @@ -28,20 +42,6 @@ bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const ModuleBase::TITLE("Ions_Move_CG", "start"); assert(Ions_Move_Basic::dim > 0); - static bool sd = false; - static bool trial = false; - static int ncggrad = 0; - static double fa = 0.0; - static double fb = 0.0; - static double fc = 0.0; - static double xa = 0.0; - static double xb = 0.0; - static double xc = 0.0; - static double xpt = 0.0; - static double steplength = 0.0; - static double fmax = 0.0; - static int nbrent = 0; - const int dim = Ions_Move_Basic::dim; std::vector pos(dim, 0.0); std::vector grad(dim, 0.0); @@ -56,19 +56,19 @@ bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const { if (istep == 1) { - steplength = Ions_Move_Basic::relax_bfgs_init; - sd = true; - trial = true; - ncggrad = 0; - fa = 0.0; - fb = 0.0; - fc = 0.0; - xa = 0.0; - xb = 0.0; - xc = 0.0; - xpt = 0.0; - fmax = 0.0; - nbrent = 0; + this->steplength = Ions_Move_Basic::relax_bfgs_init; + this->sd = true; + this->trial = true; + this->ncggrad = 0; + this->fa = 0.0; + this->fb = 0.0; + this->fc = 0.0; + this->xa = 0.0; + this->xb = 0.0; + this->xc = 0.0; + this->xpt = 0.0; + this->fmax = 0.0; + this->nbrent = 0; } Ions_Move_Basic::setup_gradient(ucell, force, pos.data(), grad.data(), ofs); @@ -85,14 +85,14 @@ bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const return true; } - if (sd) + if (this->sd) { e0 = etot_in; - CG_Base::setup_cg_grad(dim, grad.data(), grad0.data(), cg_grad.data(), cg_grad0.data(), ncggrad, flag); - ncggrad++; + CG_Base::setup_cg_grad(dim, grad.data(), grad0.data(), cg_grad.data(), cg_grad0.data(), this->ncggrad, flag); + this->ncggrad++; CG_Base::normalize(dim, cg_gradn.data(), cg_grad.data()); - CG_Base::setup_move(dim, move0.data(), cg_gradn.data(), steplength); + CG_Base::setup_move(dim, move0.data(), cg_gradn.data(), this->steplength); Ions_Move_Basic::move_atoms(ucell, move0.data(), pos.data(), ofs); for (int i = 0; i < dim; i++) @@ -101,10 +101,10 @@ bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const cg_grad0[i] = cg_grad[i]; } - CG_Base::f_cal(dim, move0.data(), move0.data(), xb); - CG_Base::f_cal(dim, move0.data(), grad.data(), fa); - fmax = fa; - sd = false; + CG_Base::f_cal(dim, move0.data(), move0.data(), this->xb); + CG_Base::f_cal(dim, move0.data(), grad.data(), this->fa); + this->fmax = this->fa; + this->sd = false; if (relax_method[0] == "cg_bfgs") { @@ -114,69 +114,69 @@ bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const relax_method[0] = "bfgs"; relax_method[1] = "1"; } - Ions_Move_Basic::best_xxx = steplength; + Ions_Move_Basic::best_xxx = this->steplength; } - Ions_Move_Basic::relax_bfgs_init = xb; + Ions_Move_Basic::relax_bfgs_init = this->xb; return false; } - if (trial) + if (this->trial) { double e1 = etot_in; - CG_Base::f_cal(dim, move0.data(), grad.data(), fb); - CG_Base::f_cal(dim, move0.data(), move0.data(), xb); + CG_Base::f_cal(dim, move0.data(), grad.data(), this->fb); + CG_Base::f_cal(dim, move0.data(), move0.data(), this->xb); - if ((std::abs(fb) < std::abs((fa) / 10.0))) + if ((std::abs(this->fb) < std::abs((this->fa) / 10.0))) { - sd = true; - trial = true; - steplength = xb; + this->sd = true; + this->trial = true; + this->steplength = this->xb; flag = 1; continue; } CG_Base::normalize(dim, cg_gradn.data(), cg_grad0.data()); - CG_Base::third_order(e0, e1, fa, fb, xb, best_x); + CG_Base::third_order(e0, e1, this->fa, this->fb, this->xb, best_x); - if (best_x > 6 * xb || best_x < (-xb)) + if (best_x > 6 * this->xb || best_x < (-this->xb)) { - best_x = 6 * xb; + best_x = 6 * this->xb; } CG_Base::setup_move(dim, move.data(), cg_gradn.data(), best_x); Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data(), ofs); - trial = false; - xa = 0; - CG_Base::f_cal(dim, move0.data(), move.data(), xc); - xc = xb + xc; - xpt = xc; - Ions_Move_Basic::relax_bfgs_init = xc; + this->trial = false; + this->xa = 0; + CG_Base::f_cal(dim, move0.data(), move.data(), this->xc); + this->xc = this->xb + this->xc; + this->xpt = this->xc; + Ions_Move_Basic::relax_bfgs_init = this->xc; return false; } double xtemp = 0.0; double ftemp = 0.0; - CG_Base::f_cal(dim, move0.data(), grad.data(), fc); - fmin = std::abs(fc); - nbrent++; + CG_Base::f_cal(dim, move0.data(), grad.data(), this->fc); + fmin = std::abs(this->fc); + this->nbrent++; - if ((fmin < std::abs((fmax) / 10.0)) || (nbrent > 3)) + if ((fmin < std::abs((this->fmax) / 10.0)) || (this->nbrent > 3)) { - nbrent = 0; - sd = true; - trial = true; - steplength = xpt; + this->nbrent = 0; + this->sd = true; + this->trial = true; + this->steplength = this->xpt; flag = 1; continue; } - CG_Base::Brent(fa, fb, fc, xa, xb, xc, best_x, xpt); - if (xc < 0) + CG_Base::Brent(this->fa, this->fb, this->fc, this->xa, this->xb, this->xc, best_x, this->xpt); + if (this->xc < 0) { - sd = true; - trial = true; - steplength = xb; + this->sd = true; + this->trial = true; + this->steplength = this->xb; flag = 2; continue; } @@ -184,7 +184,7 @@ bool Ions_Move_CG::start(UnitCell &ucell, const ModuleBase::matrix &force, const CG_Base::normalize(dim, cg_gradn.data(), cg_grad0.data()); CG_Base::setup_move(dim, move.data(), cg_gradn.data(), best_x); Ions_Move_Basic::move_atoms(ucell, move.data(), pos.data(), ofs); - Ions_Move_Basic::relax_bfgs_init = xc; + Ions_Move_Basic::relax_bfgs_init = this->xc; return false; } } \ No newline at end of file diff --git a/source/source_relax/ions_move_cg.h b/source/source_relax/ions_move_cg.h index 7e45491332d..6b44d8284f0 100644 --- a/source/source_relax/ions_move_cg.h +++ b/source/source_relax/ions_move_cg.h @@ -25,6 +25,20 @@ class Ions_Move_CG : public CG_Base std::vector cg_grad0; std::vector move0; double e0 = 0.0; + + bool sd = false; + bool trial = false; + int ncggrad = 0; + int nbrent = 0; + double fa = 0.0; + double fb = 0.0; + double fc = 0.0; + double xa = 0.0; + double xb = 0.0; + double xc = 0.0; + double xpt = 0.0; + double steplength = 0.0; + double fmax = 0.0; }; #endif \ No newline at end of file From 5cfa3fa8a4e41f08de92a730181d450dfa46ef93 Mon Sep 17 00:00:00 2001 From: abacus_fixer Date: Mon, 15 Jun 2026 16:40:48 +0800 Subject: [PATCH 50/50] remove static members in lattice_change_cg files --- source/source_relax/lattice_change_cg.cpp | 132 +++++++++++----------- source/source_relax/lattice_change_cg.h | 14 +++ 2 files changed, 80 insertions(+), 66 deletions(-) diff --git a/source/source_relax/lattice_change_cg.cpp b/source/source_relax/lattice_change_cg.cpp index 2001ca0da51..171979cf7c0 100644 --- a/source/source_relax/lattice_change_cg.cpp +++ b/source/source_relax/lattice_change_cg.cpp @@ -22,6 +22,20 @@ void Lattice_Change_CG::allocate(void) this->cg_grad0.resize(dim, 0.0); this->move0.resize(dim, 0.0); this->e0 = 0.0; + + this->sd = false; + this->trial = false; + this->ncggrad = 0; + this->nbrent = 0; + this->fa = 0.0; + this->fb = 0.0; + this->fc = 0.0; + this->xa = 0.0; + this->xb = 0.0; + this->xc = 0.0; + this->xpt = 0.0; + this->steplength = 0.0; + this->fmax = 0.0; } bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_in, const double &etot_in, std::ofstream& ofs, std::vector& etot_info) @@ -33,20 +47,6 @@ bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ assert(cg_grad0.size() == static_cast(dim)); assert(move0.size() == static_cast(dim)); - static bool sd = false; - static bool trial = false; - static int ncggrad = 0; - static double fa = 0.0; - static double fb = 0.0; - static double fc = 0.0; - static double xa = 0.0; - static double xb = 0.0; - static double xc = 0.0; - static double xpt = 0.0; - static double steplength = 0.0; - static double fmax = 0.0; - static int nbrent = 0; - std::vector lat(dim, 0.0); std::vector grad(dim, 0.0); std::vector cg_gradn(dim, 0.0); @@ -60,19 +60,19 @@ bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ { if (Lattice_Change_Basic::stress_step == 1) { - steplength = Lattice_Change_Basic::lattice_change_ini; - sd = true; - trial = true; - ncggrad = 0; - fa = 0.0; - fb = 0.0; - fc = 0.0; - xa = 0.0; - xb = 0.0; - xc = 0.0; - xpt = 0.0; - fmax = 0.0; - nbrent = 0; + this->steplength = Lattice_Change_Basic::lattice_change_ini; + this->sd = true; + this->trial = true; + this->ncggrad = 0; + this->fa = 0.0; + this->fb = 0.0; + this->fc = 0.0; + this->xa = 0.0; + this->xb = 0.0; + this->xc = 0.0; + this->xpt = 0.0; + this->fmax = 0.0; + this->nbrent = 0; } ModuleBase::matrix stress(stress_in); @@ -91,14 +91,14 @@ bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ return true; } - if (sd) + if (this->sd) { e0 = etot_in; - CG_Base::setup_cg_grad(dim, grad.data(), grad0.data(), cg_grad.data(), cg_grad0.data(), ncggrad, flag); - ncggrad++; + CG_Base::setup_cg_grad(dim, grad.data(), grad0.data(), cg_grad.data(), cg_grad0.data(), this->ncggrad, flag); + this->ncggrad++; CG_Base::normalize(dim, cg_gradn.data(), cg_grad.data()); - CG_Base::setup_move(dim, move0.data(), cg_gradn.data(), steplength); + CG_Base::setup_move(dim, move0.data(), cg_gradn.data(), this->steplength); Lattice_Change_Basic::change_lattice(ucell, move0.data(), lat.data()); for (int i = 0; i < dim; i++) @@ -107,75 +107,75 @@ bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ cg_grad0[i] = cg_grad[i]; } - CG_Base::f_cal(dim, move0.data(), move0.data(), xb); - CG_Base::f_cal(dim, move0.data(), grad.data(), fa); + CG_Base::f_cal(dim, move0.data(), move0.data(), this->xb); + CG_Base::f_cal(dim, move0.data(), grad.data(), this->fa); - fmax = fa; - sd = false; + this->fmax = this->fa; + this->sd = false; - Lattice_Change_Basic::lattice_change_ini = xb; + Lattice_Change_Basic::lattice_change_ini = this->xb; return false; } - if (trial) + if (this->trial) { double e1 = etot_in; - CG_Base::f_cal(dim, move0.data(), grad.data(), fb); - CG_Base::f_cal(dim, move0.data(), move0.data(), xb); + CG_Base::f_cal(dim, move0.data(), grad.data(), this->fb); + CG_Base::f_cal(dim, move0.data(), move0.data(), this->xb); - if ((std::abs(fb) < std::abs((fa) / 10.0))) + if ((std::abs(this->fb) < std::abs((this->fa) / 10.0))) { - sd = true; - trial = true; - steplength = xb; + this->sd = true; + this->trial = true; + this->steplength = this->xb; flag = 1; continue; } CG_Base::normalize(dim, cg_gradn.data(), cg_grad0.data()); - CG_Base::third_order(e0, e1, fa, fb, xb, best_x); + CG_Base::third_order(e0, e1, this->fa, this->fb, this->xb, best_x); - if (best_x > 6 * xb || best_x < (-xb)) + if (best_x > 6 * this->xb || best_x < (-this->xb)) { - best_x = 6 * xb; + best_x = 6 * this->xb; } CG_Base::setup_move(dim, move.data(), cg_gradn.data(), best_x); Lattice_Change_Basic::change_lattice(ucell, move.data(), lat.data()); - trial = false; - xa = 0; - CG_Base::f_cal(dim, move0.data(), move.data(), xc); - xc = xb + xc; - xpt = xc; + this->trial = false; + this->xa = 0; + CG_Base::f_cal(dim, move0.data(), move.data(), this->xc); + this->xc = this->xb + this->xc; + this->xpt = this->xc; - Lattice_Change_Basic::lattice_change_ini = xc; + Lattice_Change_Basic::lattice_change_ini = this->xc; return false; } double xtemp = 0.0; double ftemp = 0.0; - CG_Base::f_cal(dim, move0.data(), grad.data(), fc); + CG_Base::f_cal(dim, move0.data(), grad.data(), this->fc); - fmin = std::abs(fc); - nbrent++; + fmin = std::abs(this->fc); + this->nbrent++; - if ((fmin < std::abs((fmax) / 10.0)) || (nbrent > 3)) + if ((fmin < std::abs((this->fmax) / 10.0)) || (this->nbrent > 3)) { - nbrent = 0; - sd = true; - trial = true; - steplength = xpt; + this->nbrent = 0; + this->sd = true; + this->trial = true; + this->steplength = this->xpt; flag = 1; continue; } - CG_Base::Brent(fa, fb, fc, xa, xb, xc, best_x, xpt); - if (xc < 0) + CG_Base::Brent(this->fa, this->fb, this->fc, this->xa, this->xb, this->xc, best_x, this->xpt); + if (this->xc < 0) { - sd = true; - trial = true; - steplength = xb; + this->sd = true; + this->trial = true; + this->steplength = this->xb; flag = 2; continue; } @@ -184,7 +184,7 @@ bool Lattice_Change_CG::start(UnitCell &ucell, const ModuleBase::matrix &stress_ CG_Base::setup_move(dim, move.data(), cg_gradn.data(), best_x); Lattice_Change_Basic::change_lattice(ucell, move.data(), lat.data()); - Lattice_Change_Basic::lattice_change_ini = xc; + Lattice_Change_Basic::lattice_change_ini = this->xc; return false; } } \ No newline at end of file diff --git a/source/source_relax/lattice_change_cg.h b/source/source_relax/lattice_change_cg.h index 55ff2027b70..c5cea148c4e 100644 --- a/source/source_relax/lattice_change_cg.h +++ b/source/source_relax/lattice_change_cg.h @@ -23,6 +23,20 @@ class Lattice_Change_CG : public CG_Base std::vector cg_grad0; std::vector move0; double e0 = 0.0; + + bool sd = false; + bool trial = false; + int ncggrad = 0; + int nbrent = 0; + double fa = 0.0; + double fb = 0.0; + double fc = 0.0; + double xa = 0.0; + double xb = 0.0; + double xc = 0.0; + double xpt = 0.0; + double steplength = 0.0; + double fmax = 0.0; }; #endif \ No newline at end of file