Example #1
0
void test_smooth_r4<float_type>::test()
{
    // place particles along the x-axis within one half of the box,
    // put every second particle at the origin
    unsigned int npart = particle->nparticle();
    vector_type dx(0);
    dx[0] = box->edges()(0, 0) / npart / 2;

    std::vector<vector_type> r_list(particle->nparticle());
    std::vector<unsigned int> species(particle->nparticle());
    for (unsigned int k = 0; k < r_list.size(); ++k) {
        r_list[k] = (k % 2) ? k * dx : vector_type(0);
        species[k] = (k < npart_list[0]) ? 0U : 1U;  // set particle type for a binary mixture
    }
    BOOST_CHECK( set_position(*particle, r_list.begin()) == r_list.end() );
    BOOST_CHECK( set_species(*particle, species.begin()) == species.end() );

    // read forces and other stuff from device
    std::vector<float> en_pot(particle->nparticle());
    BOOST_CHECK( get_potential_energy(*particle, en_pot.begin()) == en_pot.end() );

    std::vector<vector_type> f_list(particle->nparticle());
    BOOST_CHECK( get_force(*particle, f_list.begin()) == f_list.end() );

    float const eps = std::numeric_limits<float>::epsilon();

    for (unsigned int i = 0; i < npart; ++i) {
        unsigned int type1 = species[i];
        unsigned int type2 = species[(i + 1) % npart];
        vector_type r = r_list[i] - r_list[(i + 1) % npart];
        vector_type f = f_list[i];

        // reference values from host module
        host_float_type fval, en_pot_;
        host_float_type rr = inner_prod(r, r);
        std::tie(fval, en_pot_) = (*host_potential)(rr, type1, type2);

        if (rr < host_potential->rr_cut(type1, type2)) {
            double rcut = host_potential->r_cut(type1, type2);
            // the GPU force module stores only a fraction of these values
            en_pot_ /= 2;

            // the first term is from the smoothing, the second from the potential
            // (see lennard_jones.cpp from unit tests)
            float const tolerance = 8 * eps * (1 + rcut/(rcut - std::sqrt(rr))) + 10 * eps;

            BOOST_CHECK_SMALL(norm_inf(fval * r - f), std::max(norm_inf(fval * r), 1.f) * tolerance * 2);
            BOOST_CHECK_CLOSE_FRACTION(en_pot_, en_pot[i], 2 * tolerance);
        }
        else {
            // when the distance is greater than the cutoff
            // set the force and the pair potential to zero
            fval = en_pot_ = 0;
            BOOST_CHECK_SMALL(norm_inf(f), eps);
            BOOST_CHECK_SMALL(en_pot[i], eps);
        }
    }
}
Example #2
0
 /** total energy per particle */
 double en_tot() { return en_pot() + en_kin(); }