void test_energy_gradient(){ g = Array<double>(x.size()); gnum = Array<double>(g.size()); double e = pot->get_energy_gradient(x, g); EXPECT_NEAR(e, etrue, 1e-10); pot->numerical_gradient(x, gnum, 1e-6); for (size_t k=0; k<6; ++k){ EXPECT_NEAR(g[k], gnum[k], 1e-6); } }
MODIFIED_FIRE::MODIFIED_FIRE(std::shared_ptr<pele::BasePotential> potential, pele::Array<double>& x0, double dtstart, double dtmax, double maxstep, size_t Nmin, double finc, double fdec, double fa, double astart, double tol, bool stepback) : GradientOptimizer(potential,x0,tol), //call GradientOptimizer constructor _dtstart(dtstart), _dt(dtstart), _dtmax(dtmax), _maxstep(maxstep), _Nmin(Nmin), _finc(finc), _fdec(fdec), _fa(fa), _astart(astart), _a(astart), _fold(f_), _ifnorm(0),_vnorm(0), _v(x0.size(),0), _dx(x0.size()), _xold(x0.copy()),_gold(g_.copy()), _fire_iter_number(0), _N(x_.size()), _stepback(stepback) {}
/* * computes the static pressure tensor, ignoring the momenta of the atoms * the momentum component can be added * */ double pressure_tensor(std::shared_ptr<pele::BasePotential> pot_, pele::Array<double> x, pele::Array<double> ptensor, const double volume) { pele::SimplePairwisePotentialInterface* pot = dynamic_cast<pele::SimplePairwisePotentialInterface*>(pot_.get()); if (pot == NULL) { throw std::runtime_error("pressure_tensor: illegal potential"); } const size_t ndim = pot->get_ndim(); const size_t natoms = x.size() / ndim; if (ndim * natoms != x.size()) { throw std::runtime_error("x is not divisible by the number of dimensions"); } if (ptensor.size() != ndim * ndim) { throw std::runtime_error("ptensor must have size ndim * ndim"); } double gij; double dr[ndim]; ptensor.assign(0.); for (size_t atomi = 0; atomi < natoms; ++atomi) { size_t const i1 = ndim * atomi; for (size_t atomj = 0; atomj < atomi; ++atomj) { size_t const j1 = ndim * atomj; pot->get_rij(dr, &x[i1], &x[j1]); double r2 = 0; for (size_t k = 0; k < ndim; ++k) { r2 += dr[k] * dr[k]; } pot->get_interaction_energy_gradient(r2, &gij, atomi, atomj); for (size_t k = 0; k < ndim; ++k) { for (size_t l = k; l < ndim; ++l) { ptensor[k * ndim + l] += dr[k] * gij * dr[l]; ptensor[l * ndim + k] = ptensor[k * ndim + l]; } } } } ptensor /= volume; //pressure is the average of the trace of the pressure tensor divived by the volume, here we return only the trace double traceP = 0.; for (size_t i = 0; i < ndim; ++i) { traceP += ptensor[i * ndim + i]; } return traceP / ndim; }
double GetDisplacementPerParticle::compute_mean_particle_displacement(pele::Array<double> new_coords) { if (new_coords.size() != m_initial_coordinates.size()) { throw std::runtime_error("GetMeanRMSDisplacement::compute_mean_rsm_displacement: illegal new coords"); } Moments mom; for (size_t particle = 0; particle < m_nr_particles; ++particle) { mom.update(get_particle_displ(particle, new_coords)); } return mom.mean(); }
void RecordCoordsTimeseries::action(pele::Array<double> &coords, double energy, bool accepted, MC* mc) { if (coords.size() != m_ndof) { throw std::runtime_error("RecordCoordsTimeseries::action: ndof and new coords have different size"); } size_t counter = mc->get_iterations_count(); if (counter > m_eqsteps){ this->m_update_mean_coord_vector(coords); if (counter % m_record_every == 0) { m_record_vector_value(this->get_recorded_vector(coords, energy, accepted, mc)); } } }
double bench_potential(std::shared_ptr<pele::BasePotential> pot, pele::Array<double> x, size_t neval) { auto grad = x.copy(); Timer t; t.start(); for (size_t i = 0; i < neval; ++i) { // change x by some amount and recompute the energy double dx = .1; if (i % 5 == 0) dx *= -1; x[i % x.size()] += dx; pot->get_energy_gradient(x, grad); // if (i % 500 == 0) { // std::cout << i << " energy " << energy << "\n"; // } } t.stop(); return t.get(); }
void test_energy_gradient_hessian(){ g = Array<double>(x.size()); gnum = Array<double>(g.size()); h = Array<double>(x.size()*x.size()); hnum = Array<double>(h.size()); double e = pot->get_energy_gradient_hessian(x, g, h); double ecomp = pot->get_energy(x); pot->numerical_gradient(x, gnum); pot->numerical_hessian(x, hnum); EXPECT_NEAR(e, ecomp, 1e-10); for (size_t i=0; i<g.size(); ++i){ ASSERT_NEAR(g[i], gnum[i], 1e-6); } for (size_t i=0; i<h.size(); ++i){ ASSERT_NEAR(h[i], hnum[i], 1e-3); } }
virtual void SetUp(){ c6 = 1.2; c12 = 2.3; rcut = 2.5; natoms = 4; ntypeA = 2; atomsA = pele::Array<size_t>(ntypeA); for (size_t i =0; i<atomsA.size(); ++i){ atomsA[i] = i; } size_t ntypeB = natoms - ntypeA; atomsB = pele::Array<size_t>(ntypeB); for (size_t i = 0; i<ntypeB; ++i){ atomsB[i] = i + ntypeA; } x = pele::Array<double>(3*natoms); x[0] = 0.1; x[1] = 0.2; x[2] = 0.3; x[3] = 0.44; x[4] = 0.55; x[5] = 1.66; x[6] = 0; x[7] = 0; x[8] = -3.; x[9] = 1.38; x[10] = 0.55; x[11] = 1.66; x[9] = .4; x[10] = 1.57; x[11] = 1.66; etrue = 0.65332411282951708; setup_potential(); }
GetDisplacementPerParticle::GetDisplacementPerParticle(pele::Array<double> initial_coordinates_, const size_t boxdimension_) : m_initial_coordinates(initial_coordinates_.copy()), m_boxdimension(boxdimension_), m_nr_particles(initial_coordinates_.size() / boxdimension_) {}