Esempio n. 1
0
 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);
     }
 }
Esempio n. 2
0
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)
{}
Esempio n. 3
0
/*
 * 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;
}
Esempio n. 4
0
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));
        }
    }
}
Esempio n. 6
0
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();
}
Esempio n. 7
0
    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);
        }
    }
Esempio n. 8
0
    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();
    }
Esempio n. 9
0
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_)
{}