diff --git a/src/ABPG.cc b/src/ABPG.cc index 62cb6ba1..107edc63 100644 --- a/src/ABPG.cc +++ b/src/ABPG.cc @@ -38,7 +38,7 @@ void ABPG::setup(T& orbitals) // // orthof=true: wants orthonormalized updated wave functions template -int ABPG::updateWF(T& orbitals, Ions& /*ions*/, const double precond_factor, +int ABPG::updateWF(T& orbitals, Ions& ions, const double precond_factor, const bool /*orthof*/, T& work_orbitals, const bool accelerate, const bool print_res, const double atol) { @@ -51,8 +51,8 @@ int ABPG::updateWF(T& orbitals, Ions& /*ions*/, const double precond_factor, T res("Residual", orbitals, false); const bool check_res = (atol > 0.); - double normRes = mgmol_strategy_->computeResidual( - orbitals, work_orbitals, res, (print_res || check_res), check_res); + double normRes = mgmol_strategy_->computeResidual(orbitals, work_orbitals, + ions, res, (print_res || check_res), check_res); if (normRes < atol && check_res) { abpg_nl_update_tm_.stop(); diff --git a/src/DFTsolver.cc b/src/DFTsolver.cc index 91c4a0f6..206fba91 100644 --- a/src/DFTsolver.cc +++ b/src/DFTsolver.cc @@ -196,8 +196,8 @@ double DFTsolver::evaluateEnergy( // Get the new total energy const double ts = 0.5 * proj_matrices_->computeEntropy(); // in [Ha] - eks_history_[0] - = energy_->evaluateTotal(ts, proj_matrices_, orbitals, print_flag, os_); + eks_history_[0] = energy_->evaluateTotal( + ts, proj_matrices_, ions_, orbitals, print_flag, os_); sum_eig_[1] = sum_eig_[0]; sum_eig_[0] = 2. * proj_matrices_->getEigSum(); // 2.*sum in [Ry] diff --git a/src/DavidsonSolver.cc b/src/DavidsonSolver.cc index 0dc88ef4..a049fde7 100644 --- a/src/DavidsonSolver.cc +++ b/src/DavidsonSolver.cc @@ -500,7 +500,7 @@ int DavidsonSolver::solve( ts0 = evalEntropy(projmatrices, (ct.verbose > 1), os_); e0 = energy_->evaluateTotal( - ts0, projmatrices, orbitals, printE, os_); + ts0, projmatrices, ions_, orbitals, printE, os_); retval = checkConvergence(e0, outer_it, ct.conv_tol); if (retval == 0 || (outer_it == ct.max_electronic_steps)) @@ -549,7 +549,7 @@ int DavidsonSolver::solve( ts0 = evalEntropy(proj_mat2N_.get(), (ct.verbose > 1), os_); e0 = energy_->evaluateTotal( - ts0, proj_mat2N_.get(), orbitals, printE, os_); + ts0, proj_mat2N_.get(), ions_, orbitals, printE, os_); } // 2N x 2N target... @@ -621,8 +621,8 @@ int DavidsonSolver::solve( const double ts1 = evalEntropy(proj_mat2N_.get(), (ct.verbose > 2), os_); - const double e1 = energy_->evaluateTotal( - ts1, proj_mat2N_.get(), orbitals, ct.verbose - 1, os_); + const double e1 = energy_->evaluateTotal(ts1, proj_mat2N_.get(), + ions_, orbitals, ct.verbose - 1, os_); // line minimization beta = minQuadPolynomial(e0, e1, de0, (ct.verbose > 2), os_); diff --git a/src/Energy.cc b/src/Energy.cc index 1cee6d67..f53dbc93 100644 --- a/src/Energy.cc +++ b/src/Energy.cc @@ -25,11 +25,10 @@ #define RY2HA 0.5 template -Energy::Energy(const pb::Grid& mygrid, const Ions& ions, - const Potentials& pot, const Electrostatic& es, const Rho& rho, - const XConGrid& xc, SpreadPenaltyInterface* spread_penalty) +Energy::Energy(const pb::Grid& mygrid, const Potentials& pot, + const Electrostatic& es, const Rho& rho, const XConGrid& xc, + SpreadPenaltyInterface* spread_penalty) : mygrid_(mygrid), - ions_(ions), pot_(pot), es_(es), rho_(rho), @@ -59,7 +58,7 @@ double Energy::getEVrhoRho() const } template -double Energy::evaluateEnergyIonsInVext() +double Energy::evaluateEnergyIonsInVext(Ions& ions) { double energy = 0.; @@ -69,12 +68,12 @@ double Energy::evaluateEnergyIonsInVext() //(*MPIdata::sout)<<"Energy::evaluateEnergyIonsInVext()"< positions; - positions.reserve(3 * ions_.local_ions().size()); + positions.reserve(3 * ions.local_ions().size()); // loop over ions int nions = 0; - std::vector::const_iterator ion = ions_.local_ions().begin(); - while (ion != ions_.local_ions().end()) + std::vector::const_iterator ion = ions.local_ions().begin(); + while (ion != ions.local_ions().end()) { (*ion)->getPosition(position); positions.push_back(position[0]); @@ -88,9 +87,9 @@ double Energy::evaluateEnergyIonsInVext() pot_.getValVext(positions, val); // loop over ions again - ion = ions_.local_ions().begin(); + ion = ions.local_ions().begin(); int ion_index = 0; - while (ion != ions_.local_ions().end()) + while (ion != ions.local_ions().end()) { const double z = (*ion)->getZion(); // int ion_index=(*ion)->index(); @@ -112,16 +111,16 @@ double Energy::evaluateEnergyIonsInVext() template double Energy::evaluateTotal(const double ts, // in [Ha] - ProjectedMatricesInterface* projmatrices, const T& phi, const int verbosity, - std::ostream& os) + ProjectedMatricesInterface* projmatrices, Ions& ions, const T& phi, + const int verbosity, std::ostream& os) { eval_te_tm_.start(); Control& ct = *(Control::instance()); - const double eself = ions_.energySelf(); - const double ediff = ions_.energyDiff(ct.bcPoisson); - const double eipot = evaluateEnergyIonsInVext(); + const double eself = ions.energySelf(); + const double ediff = ions.energyDiff(ct.bcPoisson); + const double eipot = evaluateEnergyIonsInVext(ions); const double eigsum = 0.5 * projmatrices->getExpectationH(); diff --git a/src/Energy.h b/src/Energy.h index e6cafd98..d55d4040 100644 --- a/src/Energy.h +++ b/src/Energy.h @@ -11,6 +11,7 @@ #define MGMOL_ENERGY_H #include "Grid.h" +#include "Ions.h" #include "Rho.h" #include "SpreadPenaltyInterface.h" #include "Timer.h" @@ -20,7 +21,6 @@ #include class Potentials; -class Ions; class Electrostatic; class ProjectedMatricesInterface; class XConGrid; @@ -29,7 +29,6 @@ template class Energy { const pb::Grid& mygrid_; - const Ions& ions_; const Potentials& pot_; const Electrostatic& es_; const Rho& rho_; @@ -45,16 +44,15 @@ class Energy double getEVrhoRho() const; public: - Energy(const pb::Grid&, const Ions&, const Potentials&, - const Electrostatic&, const Rho&, const XConGrid&, - SpreadPenaltyInterface*); + Energy(const pb::Grid&, const Potentials&, const Electrostatic&, + const Rho&, const XConGrid&, SpreadPenaltyInterface*); static Timer eval_te_tm() { return eval_te_tm_; } - double evaluateTotal(const double ts, ProjectedMatricesInterface*, + double evaluateTotal(const double ts, ProjectedMatricesInterface*, Ions&, const T& phi, const int, std::ostream&); - double evaluateEnergyIonsInVext(); + double evaluateEnergyIonsInVext(Ions&); void saveVofRho(); }; diff --git a/src/GrassmanLineMinimization.cc b/src/GrassmanLineMinimization.cc index a83d6b08..f642e0f4 100644 --- a/src/GrassmanLineMinimization.cc +++ b/src/GrassmanLineMinimization.cc @@ -29,7 +29,7 @@ Timer GrassmanLineMinimization::update_states_tm_("Grassman_update_states"); // // orthof=true: wants orthonormalized updated wave functions template -int GrassmanLineMinimization::updateWF(T& orbitals, Ions& /*ions*/, +int GrassmanLineMinimization::updateWF(T& orbitals, Ions& ions, const double precond_factor, const bool orthof, T& work_orbitals, const bool accelerate, const bool print_res, const double atol) { @@ -61,7 +61,7 @@ int GrassmanLineMinimization::updateWF(T& orbitals, Ions& /*ions*/, // Update wavefunctions const bool check_res = (atol > 0.); double normRes = mgmol_strategy_->computeResidual(orbitals, work_orbitals, - *new_grad_, (print_res || check_res), check_res); + ions, *new_grad_, (print_res || check_res), check_res); if (normRes < atol && check_res) { nl_update_tm_.stop(); diff --git a/src/HamiltonianMVPSolver.cc b/src/HamiltonianMVPSolver.cc index 4bc017dc..f90dd228 100644 --- a/src/HamiltonianMVPSolver.cc +++ b/src/HamiltonianMVPSolver.cc @@ -160,8 +160,8 @@ int HamiltonianMVPSolver::solve( // compute energy at origin const int printE = (ct.verbose > 1) ? 1 : 0; - double e0 - = energy_->evaluateTotal(ts0, projmatrices, orbitals, printE, os_); + double e0 = energy_->evaluateTotal( + ts0, projmatrices, ions_, orbitals, printE, os_); // // compute energy at end for new H @@ -189,8 +189,8 @@ int HamiltonianMVPSolver::solve( projmatrices->setHB2H(); // compute energy at end (beta=1.) - double e1 - = energy_->evaluateTotal(ts1, projmatrices, orbitals, printE, os_); + double e1 = energy_->evaluateTotal( + ts1, projmatrices, ions_, orbitals, printE, os_); // // evaluate energy at mid-point @@ -226,8 +226,8 @@ int HamiltonianMVPSolver::solve( projmatrices->setHB2H(); // compute energy at midpoint - double ei - = energy_->evaluateTotal(tsi, projmatrices, orbitals, printE, os_); + double ei = energy_->evaluateTotal( + tsi, projmatrices, ions_, orbitals, printE, os_); // line minimization double beta @@ -285,7 +285,7 @@ int HamiltonianMVPSolver::solve( // compute energy at end (beta=1.) ei = energy_->evaluateTotal( - tsi, projmatrices, orbitals, printE, os_); + tsi, projmatrices, ions_, orbitals, printE, os_); // line minimization beta = minQuadPolynomialFrom3values( diff --git a/src/Ions.cc b/src/Ions.cc index 3b128b0e..ef9d687c 100644 --- a/src/Ions.cc +++ b/src/Ions.cc @@ -70,8 +70,18 @@ void writeData2d(HDFrestart& h5f_file, std::string datasetname, } } -Ions::Ions(const double lat[3], const std::vector& sp) : species_(sp) +Ions::Ions(const double lat[3], const std::vector& sp) + : species_(sp), setup_(false), has_locked_atoms_(false) { + setupSubdomains(lat); +} + +void Ions::setupSubdomains(const double lat[3]) +{ + MGmol_MPI& mmpi = *(MGmol_MPI::instance()); + Mesh* mymesh = Mesh::instance(); + const pb::PEenv& myPEenv = mymesh->peenv(); + for (short i = 0; i < 3; i++) { assert(lat[i] > 0.); @@ -79,15 +89,10 @@ Ions::Ions(const double lat[3], const std::vector& sp) : species_(sp) { (*MPIdata::serr) << "Ions constructor: lattice[" << i << "]=" << lat[i] << "!!!" << std::endl; - exit(2); + mmpi.abort(); } lattice_[i] = lat[i]; } - setup_ = false; - has_locked_atoms_ = false; - - Mesh* mymesh = Mesh::instance(); - const pb::PEenv& myPEenv = mymesh->peenv(); for (short i = 0; i < 3; i++) div_lattice_[i] = lattice_[i] / (double)(myPEenv.n_mpi_task(i)); @@ -107,6 +112,20 @@ Ions::Ions(const double lat[3], const std::vector& sp) : species_(sp) MPI_Cart_shift(cart_comm_, dir, disp, &source_[dir], &dest_[dir]); } +Ions::Ions(const std::vector& p, const std::vector& anum, + const double lat[3], const std::vector& sp) + : species_(sp) +{ + setupSubdomains(lat); + + double rmax = getMaxListRadius(); + setupListIonsBoundaries(rmax); + + num_ions_ = setAtoms(p, anum); + + setup(); +} + Ions::Ions(const Ions& ions, const double shift[3]) : species_(ions.species_) { for (const auto& ion : ions.list_ions_) @@ -181,8 +200,6 @@ void Ions::setup() ions_setup_tm.start(); - Ion::resetIndexCount(); - updateListIons(); //#ifndef NDEBUG @@ -197,7 +214,7 @@ void Ions::setup() has_locked_atoms_ = hasLockedAtoms(); // initialize data for constraints - setupContraintsData(interacting_ions_); + setupContraintsData(); computeMaxNumProjs(); @@ -297,13 +314,13 @@ void Ions::setupInteractingIons() // setup arrays to be used in constraints enforcement // using references to local_ions and extra "dummy" data -void Ions::setupContraintsData(std::vector& ions_for_constraints) +void Ions::setupContraintsData() { Control& ct = *(Control::instance()); if (ct.verbose > 0) printWithTimeStamp("Ions::setupContraintsData()...", std::cout); - const int nnloc = ions_for_constraints.size() - local_ions_.size(); + const int nnloc = interacting_ions_.size() - local_ions_.size(); // std::cout<<"interacting_ions_.size()="<::finalEnergy() // Get the total energy const double ts = 0.5 * proj_matrices_->computeEntropy(); // in [Ha] total_energy_ = energy_->evaluateTotal( - ts, proj_matrices_.get(), *current_orbitals_, 2, os_); + ts, proj_matrices_.get(), *ions_, *current_orbitals_, 2, os_); } template @@ -828,7 +827,7 @@ void MGmol::setupPotentials(Ions& ions) pot.initialize(ions); if (ct.verbose > 0) printWithTimeStamp("Setup kbpsi...", os_); - g_kbpsi_->setup(*ions_); + g_kbpsi_->setup(ions); electrostat_->setupRhoc(pot.rho_comp()); @@ -1170,8 +1169,8 @@ void MGmol::precond_mg(OrbitalsType& phi) template double MGmol::computeResidual(OrbitalsType& orbitals, - OrbitalsType& work_orbitals, OrbitalsType& res, const bool print_residual, - const bool norm_res) + OrbitalsType& work_orbitals, Ions& ions, OrbitalsType& res, + const bool print_residual, const bool norm_res) { assert(orbitals.getIterativeIndex() >= 0); @@ -1190,7 +1189,7 @@ double MGmol::computeResidual(OrbitalsType& orbitals, // get H*psi stored in work_orbitals.psi // and psi^T H psi in Hij - getHpsiAndTheta(*ions_, orbitals, work_orbitals); + getHpsiAndTheta(ions, orbitals, work_orbitals); double norm2Res = computeConstraintResidual( orbitals, work_orbitals, res, print_residual, norm_res); @@ -1428,17 +1427,22 @@ double MGmol::evaluateEnergyAndForces(Orbitals* orbitals, Control& ct = *(Control::instance()); - ions_->setPositions(tau, atnumbers); + // create a new temporary Ions object to be used for + // energy end forces calculation + Mesh* mymesh = Mesh::instance(); + const pb::Grid& mygrid = mymesh->grid(); + const double lattice[3] = { mygrid.ll(0), mygrid.ll(1), mygrid.ll(2) }; + Ions ions(tau, atnumbers, lattice, ions_->getSpecies()); - setupPotentials(*ions_); + setupPotentials(ions); double eks = 0.; OrbitalsType* dorbitals = dynamic_cast(orbitals); - quench(*dorbitals, *ions_, ct.max_electronic_steps, 20, eks); + quench(*dorbitals, ions, ct.max_electronic_steps, 20, eks); - force(*dorbitals, *ions_); + force(*dorbitals, ions); - ions_->getForces(forces); + ions.getForces(forces); return eks; } @@ -1450,37 +1454,42 @@ double MGmol::evaluateDMandEnergyAndForces(Orbitals* orbitals, { OrbitalsType* dorbitals = dynamic_cast(orbitals); - ions_->setPositions(tau, atnumbers); + // create a new temporary Ions object to be used for + // energy end forces calculation + Mesh* mymesh = Mesh::instance(); + const pb::Grid& mygrid = mymesh->grid(); + const double lattice[3] = { mygrid.ll(0), mygrid.ll(1), mygrid.ll(2) }; + Ions ions(tau, atnumbers, lattice, ions_->getSpecies()); - setupPotentials(*ions_); + setupPotentials(ions); // initialize electronic density rho_->update(*dorbitals); // initialize potential - update_pot(*ions_); + update_pot(ions); // initialize projected matrices - updateHmatrix(*dorbitals, *ions_); + updateHmatrix(*dorbitals, ions); proj_matrices_->updateThetaAndHB(); // compute DM std::shared_ptr> dm_strategy( DMStrategyFactory>::create(comm_, os_, *ions_, + dist_matrix::DistMatrix>::create(comm_, os_, ions, rho_.get(), energy_.get(), electrostat_.get(), this, proj_matrices_.get(), dorbitals)); dm_strategy->update(*dorbitals); // evaluate energy and forces - double ts = 0.; - double eks - = energy_->evaluateTotal(ts, proj_matrices_.get(), *dorbitals, 2, os_); + double ts = 0.; + double eks = energy_->evaluateTotal( + ts, proj_matrices_.get(), ions, *dorbitals, 2, os_); - force(*dorbitals, *ions_); + force(*dorbitals, ions); - ions_->getForces(forces); + ions.getForces(forces); return eks; } diff --git a/src/MGmol.h b/src/MGmol.h index 12197dfd..c85e7b59 100644 --- a/src/MGmol.h +++ b/src/MGmol.h @@ -335,17 +335,13 @@ class MGmol : public MGmolInterface void precond_mg(OrbitalsType& orbitals); void setGamma(const pb::Lap& lapOper, const Potentials& pot); double computeResidual(OrbitalsType& orbitals, OrbitalsType& work_orbitals, - OrbitalsType& res, const bool print_residual, const bool norm_res); + Ions& ions, OrbitalsType& res, const bool print_residual, + const bool norm_res); void applyAOMMprojection(OrbitalsType&); void force(OrbitalsType& orbitals, Ions& ions) { forces_->force(orbitals, ions); } - void setPositions(const std::vector& positions, - const std::vector& atnumbers) - { - ions_->setPositions(positions, atnumbers); - } /* * simply dump current state diff --git a/src/MGmolInterface.h b/src/MGmolInterface.h index dc54a8e7..9a9bf8a6 100644 --- a/src/MGmolInterface.h +++ b/src/MGmolInterface.h @@ -40,9 +40,6 @@ class MGmolInterface virtual void getAtomicPositions(std::vector& tau) = 0; virtual void getAtomicNumbers(std::vector& an) = 0; - virtual void setPositions(const std::vector& positions, - const std::vector& atnumbers) - = 0; virtual std::shared_ptr getProjectedMatrices() = 0; virtual void dumpRestart() = 0; diff --git a/src/MVPSolver.cc b/src/MVPSolver.cc index 7ab9f665..6990e29d 100644 --- a/src/MVPSolver.cc +++ b/src/MVPSolver.cc @@ -256,7 +256,7 @@ int MVPSolver::solve(OrbitalsType& orbitals) const double ts0 = evalEntropyMVP(current_proj_mat, (ct.verbose > 1), os_); const double e0 = energy_->evaluateTotal( - ts0, current_proj_mat, orbitals, printE, os_); + ts0, current_proj_mat, ions_, orbitals, printE, os_); MatrixType target("target", numst_, numst_); @@ -309,7 +309,7 @@ int MVPSolver::solve(OrbitalsType& orbitals) const double ts1 = evalEntropyMVP(proj_mat_work_, (ct.verbose > 2), os_); const double e1 = energy_->evaluateTotal( - ts1, proj_mat_work_, orbitals, ct.verbose - 1, os_); + ts1, proj_mat_work_, ions_, orbitals, ct.verbose - 1, os_); // line minimization const double beta diff --git a/src/PolakRibiereSolver.cc b/src/PolakRibiereSolver.cc index 6b5f88de..3f46a00e 100644 --- a/src/PolakRibiereSolver.cc +++ b/src/PolakRibiereSolver.cc @@ -243,9 +243,9 @@ double PolakRibiereSolver::evaluateEnergy( const OrbitalsType& orbitals, const bool print_flag) { // Get the new total energy - const double ts = 0.5 * proj_matrices_->computeEntropy(); // in [Ha] - const double energy - = energy_->evaluateTotal(ts, proj_matrices_, orbitals, print_flag, os_); + const double ts = 0.5 * proj_matrices_->computeEntropy(); // in [Ha] + const double energy = energy_->evaluateTotal( + ts, proj_matrices_, ions_, orbitals, print_flag, os_); // Control& ct(*(Control::instance())); // if( ct.verbose>2 && onpe0 )os_<<"energy="<::solve(OrbitalsType& orbitals, // evaluate residuals, preconditioned residuals for current orbitals double normRes = mgmol_strategy_->computeResidual(orbitals, - work_orbitals, *r_k_, (print_res || ct.checkResidual()), + work_orbitals, ions_, *r_k_, (print_res || ct.checkResidual()), ct.checkResidual()); if (normRes < ct.conv_tol && ct.checkResidual()) { diff --git a/src/lbfgsrlx.cc b/src/lbfgsrlx.cc index 6698eef0..ce05c1a3 100644 --- a/src/lbfgsrlx.cc +++ b/src/lbfgsrlx.cc @@ -14,7 +14,6 @@ #include "Energy.h" #include "Ions.h" #include "LBFGS.h" -#include "LBFGS_IonicStepper.h" #include "LocalizationRegions.h" #include "MGmol.h" #include "MGmol_blas1.h" diff --git a/src/quench.cc b/src/quench.cc index 073798f6..6eed74bb 100644 --- a/src/quench.cc +++ b/src/quench.cc @@ -600,8 +600,8 @@ int MGmol::quench(OrbitalsType& orbitals, Ions& ions, << " TS [Ha] = " << ts << std::endl; } } - last_eks - = energy_->evaluateTotal(ts, proj_matrices_.get(), orbitals, 2, os_); + last_eks = energy_->evaluateTotal( + ts, proj_matrices_.get(), ions, orbitals, 2, os_); if (ct.computeCondGramMD()) { diff --git a/tests/RestartEnergyAndForces/testRestartEnergyAndForces.cc b/tests/RestartEnergyAndForces/testRestartEnergyAndForces.cc index 3027ab55..b1fb0094 100644 --- a/tests/RestartEnergyAndForces/testRestartEnergyAndForces.cc +++ b/tests/RestartEnergyAndForces/testRestartEnergyAndForces.cc @@ -124,8 +124,6 @@ int main(int argc, char** argv) } } - mgmol->setPositions(positions, anumbers); - Mesh* mymesh = Mesh::instance(); const pb::Grid& mygrid = mymesh->grid(); const pb::PEenv& myPEenv = mymesh->peenv(); @@ -195,8 +193,6 @@ int main(int argc, char** argv) } } - mgmol->setPositions(positions, anumbers); - // // evaluate energy and forces with wavefunctions just read //