Mentions légales du service

Skip to content
Snippets Groups Projects
Commit 825c772e authored by GICQUEL Antoine's avatar GICQUEL Antoine :zzz:
Browse files

Minor changes in example folder

parent d56d7293
Branches
No related tags found
No related merge requests found
...@@ -23,8 +23,6 @@ set(source_tests_files ...@@ -23,8 +23,6 @@ set(source_tests_files
# test to move in compose/sandox project # test to move in compose/sandox project
fmm_source_target.cpp fmm_source_target.cpp
tutorial.cpp tutorial.cpp
playground.cpp
) )
if(${CMAKE_PROJECT_NAME}_USE_MPI) if(${CMAKE_PROJECT_NAME}_USE_MPI)
......
#include <random>
#include <vector>
#include "scalfmm/algorithms/fmm.hpp"
#include "scalfmm/algorithms/full_direct.hpp"
#include "scalfmm/container/particle.hpp"
#include "scalfmm/interpolation/interpolation.hpp"
#include "scalfmm/matrix_kernels/laplace.hpp"
#include "scalfmm/operators/fmm_operators.hpp"
#include "scalfmm/tree/box.hpp"
#include "scalfmm/tree/cell.hpp"
#include "scalfmm/tree/for_each.hpp"
#include "scalfmm/tree/group_tree_view.hpp"
#include "scalfmm/tree/leaf_view.hpp"
#include "scalfmm/utils/accurater.hpp"
#include "scalfmm/meta/utils.hpp"
#include "scalfmm/algorithms/common.hpp"
#include "scalfmm/operators/m2p.hpp"
template<typename TreeType, typename NearFieldType, typename FarFieldType>
inline auto local_sequential(TreeType& tree,
scalfmm::operators::fmm_operators<NearFieldType, FarFieldType> const& fmmoperators) -> void
{
std::cout << cpp_tools::colors::green << "LOCAL SEQUENTIAL" << cpp_tools::colors::reset << std::endl;
auto const& approximation = fmmoperators.far_field().approximation();
auto const& neighbour_separation = fmmoperators.near_field().separation_criterion();
auto const& mutual = fmmoperators.near_field().mutual();
if(tree.is_interaction_m2l_lists_built() == false)
{
scalfmm::list::sequential::build_m2l_interaction_list(tree, tree, neighbour_separation);
}
if(tree.is_interaction_p2p_lists_built() == false)
{
scalfmm::list::sequential::build_p2p_interaction_list(tree, tree, neighbour_separation, mutual);
}
if(tree.height() == 2)
{
scalfmm::algorithms::sequential::pass::direct(tree, tree, fmmoperators.near_field());
}
else
{
scalfmm::algorithms::sequential::pass::leaf_to_cell(tree, fmmoperators.far_field());
scalfmm::algorithms::sequential::pass::upward(tree, approximation);
scalfmm::algorithms::sequential::pass::transfer(tree, tree, fmmoperators.far_field());
scalfmm::algorithms::sequential::pass::downward(tree, approximation);
scalfmm::algorithms::sequential::pass::cell_to_leaf(tree, fmmoperators);
scalfmm::algorithms::sequential::pass::direct(tree, tree, fmmoperators.near_field());
}
}
namespace scalfmm::algorithms::sequential::pass
{
template<typename TreeType, typename FarFieldType>
inline auto single_level_transfer(TreeType& tree, FarFieldType const& far_field) -> void
{
std::cout << cpp_tools::colors::green << "SINGLE LEVEL TRANSFER" << cpp_tools::colors::reset << std::endl;
using operators::m2p;
auto begin = std::begin(tree);
auto end = std::end(tree);
auto group_of_leaf_begin = std::get<0>(begin);
auto group_of_leaf_end = std::get<0>(end);
auto tree_height = tree.height();
auto& cells_at_leaf_level = *(std::get<1>(begin) + (tree_height - 1));
auto group_of_cell_begin = std::begin(cells_at_leaf_level);
auto group_of_cell_end = std::end(cells_at_leaf_level);
while(group_of_leaf_begin != group_of_leaf_end && group_of_cell_begin != group_of_cell_end)
{
for(std::size_t target_leaf_index = 0; target_leaf_index < (*group_of_leaf_begin)->size();
++target_leaf_index)
{
auto const& target_cell = (*group_of_cell_begin)->ccomponent(target_leaf_index);
auto& target_leaf = (*group_of_leaf_begin)->component(target_leaf_index);
std::cout << "\t- target_cell = " << target_cell.index() << std::endl;
auto const& cell_symbolics = target_cell.csymbolics();
auto const& interaction_positions = cell_symbolics.interaction_positions;
auto const& interaction_iterators = cell_symbolics.interaction_iterators;
for(std::size_t source_index{0}; source_index < cell_symbolics.existing_neighbors; ++source_index)
{
auto const& source_cell = *interaction_iterators.at(source_index);
const auto neighbor_idx = static_cast<std::size_t>(interaction_positions.at(source_index));
std::cout << "\t- interaction between target cell " << target_cell.index() << " and source cell "
<< source_cell.index() << std::endl;
m2p(far_field, source_cell, target_leaf);
}
}
++group_of_leaf_begin;
++group_of_cell_begin;
}
}
} // namespace scalfmm::algorithms::sequential::pass
template<typename TreeType, typename NearFieldType, typename FarFieldType>
inline auto single_level_local_sequential(
TreeType& tree, scalfmm::operators::fmm_operators<NearFieldType, FarFieldType> const& fmmoperators) -> void
{
std::cout << cpp_tools::colors::green << "SINGLE LEVEL LOCAL SEQUENTIAL" << cpp_tools::colors::reset << std::endl;
auto const& approximation = fmmoperators.far_field().approximation();
auto const& neighbour_separation = fmmoperators.near_field().separation_criterion();
auto const& mutual = fmmoperators.near_field().mutual();
if(tree.is_interaction_m2l_lists_built() == false)
{
scalfmm::list::sequential::build_m2l_interaction_list(tree, tree, neighbour_separation);
}
if(tree.is_interaction_p2p_lists_built() == false)
{
scalfmm::list::sequential::build_p2p_interaction_list(tree, tree, neighbour_separation, mutual);
}
if(tree.height() == 2)
{
scalfmm::algorithms::sequential::pass::direct(tree, tree, fmmoperators.near_field());
}
else
{
scalfmm::algorithms::sequential::pass::leaf_to_cell(tree, fmmoperators.far_field());
scalfmm::algorithms::sequential::pass::single_level_transfer(tree, fmmoperators.far_field());
scalfmm::algorithms::sequential::pass::direct(tree, tree, fmmoperators.near_field());
}
}
auto main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) -> int
{
// order of the approximation
const std::size_t order{5};
// height of the fmm tree
const std::size_t tree_height{3};
// using namespace scalfmm;
using value_type = double;
// choosing a matrix kernel
// the far field matrix kernel
using far_kernel_matrix_type = scalfmm::matrix_kernels::laplace::one_over_r;
// the near field matrix kernel
using near_kernel_matrix_type = far_kernel_matrix_type;
// number of inputs and outputs.
static constexpr std::size_t nb_inputs_near{near_kernel_matrix_type::km};
static constexpr std::size_t nb_outputs_near{near_kernel_matrix_type::kn};
// loading data in containers
static constexpr std::size_t dimension{2};
// particle type
using particle_type = scalfmm::container::particle<value_type, dimension, value_type, nb_inputs_near, value_type,
nb_outputs_near, std::size_t>;
// position point type
using position_type = typename particle_type::position_type;
using container_type = std::vector<particle_type>;
// allocate 100 particles.
const std::size_t nb_particles{1000};
container_type container(nb_particles);
// box of the simulation [0,2]x[0,2]
using box_type = scalfmm::component::box<position_type>;
// width of the box
const value_type box_width{2.};
// center of the box
const position_type box_center(1.);
// the box for the tree
box_type box(box_width, box_center);
// random generator
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<value_type> dis(0.0, 2.0);
auto random_r = [&dis, &gen]() { return dis(gen); };
// inserting particles in the container
for(std::size_t idx = 0; idx < nb_particles; ++idx)
{
// particle_type p;
particle_type& p = container[idx];
for(auto& e: p.position())
{
e = random_r();
}
for(auto& e: p.inputs())
{
e = random_r();
}
for(auto& e: p.outputs())
{
e = value_type(0.);
}
p.variables(idx);
}
// interpolation types
// we define a near_field from its matrix kernel
using near_field_type = scalfmm::operators::near_field_operator<near_kernel_matrix_type>;
// we choose an interpolator with a far matrix kernel for the approximation
using interpolator_type = scalfmm::interpolation::interpolator<value_type, dimension, far_kernel_matrix_type,
scalfmm::options::uniform_<scalfmm::options::fft_>>;
// then, we define the far field
using far_field_type = scalfmm::operators::far_field_operator<interpolator_type>;
// the resulting fmm operator is
using fmm_operator_type = scalfmm::operators::fmm_operators<near_field_type, far_field_type>;
// construct the fmm operator
// construct the near field
near_field_type near_field;
// a reference on the matrix_kernel of the near_field
auto near_mk = near_field.matrix_kernel();
// build the approximation used in the near field
interpolator_type interpolator(order, tree_height, box.width(0));
far_field_type far_field(interpolator);
// construct the fmm operator
fmm_operator_type fmm_operator(near_field, far_field);
// tree types
// the cell type of the tree holding multipoles and locals expansions
// here, we extract the correct storage for the cells from the interpolation method.
using cell_type = scalfmm::component::cell<typename interpolator_type::storage_type>;
// the leaf type holding the particles
using leaf_type = scalfmm::component::leaf_view<particle_type>;
// the tree type
using group_tree_type = scalfmm::component::group_tree_view<cell_type, leaf_type, box_type>;
// we construct the tree
const std::size_t group_size{10}; // the number of cells and leaf grouped in the tree
group_tree_type tree(tree_height, order, box, group_size, group_size, container);
// now we have everything to call the fmm algorithm
single_level_local_sequential(tree, fmm_operator);
// we will compute the reference with the full direct algorithm
// from the original container
scalfmm::algorithms::full_direct(container, near_mk);
scalfmm::utils::accurater<value_type> error;
scalfmm::component::for_each_leaf(std::cbegin(tree), std::cend(tree),
[&container, &error](auto const& leaf)
{
// loop on the particles of the leaf
for(auto const p_ref: leaf)
{
// build a particle
const auto p = typename leaf_type::const_proxy_type(p_ref);
//
const auto& idx = std::get<0>(p.variables());
auto const& output_ref = container[idx].outputs();
auto const& output = p.outputs();
for(std::size_t i{0}; i < nb_outputs_near; ++i)
{
error.add(output_ref.at(i), output.at(i));
}
}
});
std::cout << error << '\n';
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment