diff --git a/experimental/include/scalfmm/interpolation/uniform.hpp b/experimental/include/scalfmm/interpolation/uniform.hpp index a5ee5437708dfb9f3798259e18134aed36c744b4..c161d9aff5b40826a952b435f7c578b6834cd702 100644 --- a/experimental/include/scalfmm/interpolation/uniform.hpp +++ b/experimental/include/scalfmm/interpolation/uniform.hpp @@ -54,6 +54,8 @@ namespace scalfmm::interpolation { + // uniform_interpolator is a CRTP based class + // meaning that it implements the functions needed by the interpolator class template<typename ValueType, std::size_t Dimension, typename FarFieldMatrixKernel> struct uniform_interpolator : public interpolator<uniform_interpolator<ValueType, Dimension, FarFieldMatrixKernel>> { @@ -286,10 +288,12 @@ namespace scalfmm::interpolation inline auto generate_interactions_matrixes_impl(value_type width, std::size_t tree_height) -> void { std::size_t number_of_level{1}; - std::size_t number_of_interactions{this->m2l_interactions()}; + const std::size_t number_of_interactions{this->m2l_interactions()}; // here width is the root width // so first level of cell is of width because we skip level 0 (the root) and (the first level)): value_type current_width{width}; + const value_type half{0.5}; + const value_type quarter{0.25}; // we get the half width to scale the roots if constexpr (base_type::homogeneity_tag == matrix_kernels::homogeneity::non_homogenous) @@ -297,10 +301,10 @@ namespace scalfmm::interpolation // (tree_heigh = 4 -> [0-3]) the bottom cells and leaves have the same symbolic level ! // but we remove level 0 (the root ie simulaton box) and level 1. number_of_level = tree_height-2; - current_width = width*0.25; + current_width = width*quarter; } - value_type half_width{current_width*0.5}; + value_type half_width{current_width*half}; // we need to keep the tensorial view // let the same view goes down to tensorial of point // X and Y are Td tensors storing point. @@ -390,8 +394,8 @@ namespace scalfmm::interpolation meta::looper_range<dimension>{}(generate_all_interactions, starts, stops); // we divide the widths for the next tree level - current_width *= 0.5; - half_width *= 0.5; + current_width *= half; + half_width *= half; } } diff --git a/experimental/include/scalfmm/matrix_kernels/debug.hpp b/experimental/include/scalfmm/matrix_kernels/debug.hpp new file mode 100644 index 0000000000000000000000000000000000000000..dc325f41341b835732867741b162e14370397519 --- /dev/null +++ b/experimental/include/scalfmm/matrix_kernels/debug.hpp @@ -0,0 +1,68 @@ +// -------------------------------- +// See LICENCE file at project root +// File : matrix_kernels/debug.hpp +// -------------------------------- +#ifndef SCALFMM_MATRIX_KERNELS_DEBUG_HPP +#define SCALFMM_MATRIX_KERNELS_DEBUG_HPP + +#include <array> +#include <cmath> +#include <limits> +#include <tuple> +#include <type_traits> +#include <utility> + +#include <xtensor/xmath.hpp> + +#include "scalfmm/meta/utils.hpp" +#include <scalfmm/container/point.hpp> +#include <scalfmm/matrix_kernels/mk_common.hpp> +#include <scalfmm/meta/utils.hpp> +#include <scalfmm/utils/math.hpp> + +namespace scalfmm::matrix_kernels::debug +{ + // This matrix kernel is here to debug the non homogenous case + struct one_over_r_non_homogenous + { + static constexpr auto homogeneity_tag{homogeneity::non_homogenous}; + static constexpr std::size_t km{1}; + static constexpr std::size_t kn{1}; + + template<typename ValueType> + [[nodiscard]] inline constexpr auto mutual_coefficient() const + { + return std::make_tuple(ValueType(1.)); + } + + template<typename ValueType, std::size_t Dim> + [[nodiscard]] inline auto evaluate(container::point<ValueType, Dim> const& x, + container::point<ValueType, Dim> const& y) const noexcept + { + return variadic_evaluate(x, y, std::make_index_sequence<Dim>{}); + } + + template<typename ValueType> + [[nodiscard]] inline auto scale_factor(ValueType cell_width) const noexcept + { + return std::make_tuple(ValueType(1.)); + } + + template<typename ValueType> + [[nodiscard]] inline auto scale_factor(ValueType cell_width, std::size_t tree_level) const noexcept + { + return scale_factor(cell_width / math::pow(ValueType(2.), tree_level)); + } + + template<typename ValueType, std::size_t Dim, std::size_t... Is> + [[nodiscard]] inline auto variadic_evaluate(container::point<ValueType, Dim> const& xs, + container::point<ValueType, Dim> const& ys, + std::index_sequence<Is...> is) const noexcept + { + using std::sqrt; + return std::make_tuple(ValueType(1.0) / sqrt((((xs.at(Is) - ys.at(Is)) * (xs.at(Is) - ys.at(Is))) + ...))); + } + const std::size_t separation_criterion{1}; + }; +} +#endif // SCALFMM_MATRIX_KERNELS_DEBUG_HPP diff --git a/experimental/include/scalfmm/matrix_kernels/laplace.hpp b/experimental/include/scalfmm/matrix_kernels/laplace.hpp index 6261df2a3c778a2b8402937cbf0892d95b1b006a..7efdb0f3299152b182cdeb675c560945b7e0cc04 100644 --- a/experimental/include/scalfmm/matrix_kernels/laplace.hpp +++ b/experimental/include/scalfmm/matrix_kernels/laplace.hpp @@ -71,6 +71,7 @@ namespace scalfmm::matrix_kernels::laplace } const std::size_t separation_criterion{1}; }; + /////// /// \brief The like_mrhs simulates two FMMs with independent charges /// diff --git a/experimental/include/scalfmm/tree/for_each.hpp b/experimental/include/scalfmm/tree/for_each.hpp index ff0532b5358677ec95aed627e0d34f2b09c44d9f..6890918b82e317cddde37a781e9ca564c89469c8 100644 --- a/experimental/include/scalfmm/tree/for_each.hpp +++ b/experimental/include/scalfmm/tree/for_each.hpp @@ -5,6 +5,7 @@ #ifndef SCALFMM_TREE_FOR_EACH_HPP #define SCALFMM_TREE_FOR_EACH_HPP +#include <bits/c++config.h> #include <functional> #include <utility> @@ -39,6 +40,29 @@ namespace scalfmm::component return f; } + template<typename InputTreeIterator, typename BinaryFunction> + inline auto for_each_leaf(InputTreeIterator begin, InputTreeIterator end, InputTreeIterator begin2, BinaryFunction f) -> BinaryFunction + { + auto group_leaf_iterator_begin = std::get<0>(begin); + auto group_leaf_iterator_end = std::get<0>(end); + auto group_leaf_iterator_begin2 = std::get<0>(begin2); + + for(; group_leaf_iterator_begin != group_leaf_iterator_end; ++group_leaf_iterator_begin) + { + auto begin_leaf = std::begin((*group_leaf_iterator_begin)->block()); + auto begin_leaf2 = std::begin((*group_leaf_iterator_begin2)->block()); + for(std::size_t i{0}; i<(*group_leaf_iterator_begin)->block().size(); ++i) + { + f(*begin_leaf, *begin_leaf2); + ++begin_leaf; + ++begin_leaf2; + } + ++group_leaf_iterator_begin2; + } + + return f; + } + template<typename InputTreeIterator, typename UnaryFunction> inline auto for_each_cell(InputTreeIterator begin, InputTreeIterator end, std::size_t level, UnaryFunction f) -> UnaryFunction diff --git a/experimental/units/CMakeLists.txt b/experimental/units/CMakeLists.txt index 47425f03abadef81d60996318a997f0137767565..d46811c88522db7b925b4aa9a82eac00932d2bdd 100644 --- a/experimental/units/CMakeLists.txt +++ b/experimental/units/CMakeLists.txt @@ -8,6 +8,7 @@ set(source_tests_files operators/l2p.cpp fmm/test_dimension.cpp fmm/count_kernel.cpp + fmm/test_non_homogenous.cpp ) set(TEST_FILES_PATH ${CMAKE_SOURCE_DIR}/units/fmm/) @@ -47,36 +48,3 @@ endforeach(exec) add_custom_target(units ALL DEPENDS ${SCALFMM_UNITS_TARGETS}) -#if(SCALFMM_ONLY_DEVEL) -# set(source_check_files -# operators/interp.cpp -# operators/l2p.cpp -# ) - -# foreach(exec ${source_check_files}) -# set(compile_exec TRUE) -# get_filename_component( execname ${exec} NAME_WE ) - -# foreach(fuse_key ${FUSE_DEP_AVAILABLE}) -# file(STRINGS "${exec}" lines_fuse REGEX "@FUSE_${fuse_key}") -# if(lines_fuse AND NOT ${fuse_key} IN_LIST FUSE_LIST) -# message( STATUS "This needs ${fuse_key} = ${exec}" ) -# set(compile_exec FALSE) -# endif() -# endforeach() - -# # Dependency are OK -# if( compile_exec ) -# add_executable( check.${execname} ${exec}) -# set_target_properties(check.${execname} PROPERTIES -# RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BUILD_TYPE} -# ) - -# target_link_libraries( check.${execname} PRIVATE ${CMAKE_PROJECT_NAME}) -# target_include_directories(check.${execname} PRIVATE ${CMAKE_SOURCE_DIR}/modules/external/catch2/) -# # list(APPEND SCALFMM_UNITS_TARGETS check.${execname}) - -# endif() -# endforeach(exec) -#endif(SCALFMM_ONLY_DEVEL) - diff --git a/experimental/units/fmm/test_dimension.cpp b/experimental/units/fmm/test_dimension.cpp index 0f6001c04d6ba4cb8e63934d25a9a501186fae86..bf5c49cb89be476067d56d7848dbe1fb623a0a5f 100644 --- a/experimental/units/fmm/test_dimension.cpp +++ b/experimental/units/fmm/test_dimension.cpp @@ -47,7 +47,6 @@ using namespace scalfmm; template<int Dimension, typename CONTAINER_T, typename POINT_T, typename VALUE_T> void read_data(const std::string& filename, CONTAINER_T*& container, POINT_T& Centre, VALUE_T& width) { - // std::cout << "READ DATA " << std::endl << std::flush; using particle_type = typename CONTAINER_T::particle_type; scalfmm::tools::FFmaGenericLoader<VALUE_T, Dimension> loader(filename); @@ -55,14 +54,9 @@ void read_data(const std::string& filename, CONTAINER_T*& container, POINT_T& Ce const int number_of_particles = loader.getNumberOfParticles(); width = loader.getBoxWidth(); Centre = loader.getBoxCenter(); - // std::size_t i{0}; - // for(auto& e: Centre) - // { - // e = Centre_3D[i++]; - // } auto nb_val_to_red_per_part = loader.getNbRecordPerline(); - double* values_to_read = new double[nb_val_to_red_per_part]{0}; + VALUE_T* values_to_read = new VALUE_T[nb_val_to_red_per_part]{0}; container = new CONTAINER_T(number_of_particles); std::cout << "number_of_particles " << number_of_particles << std::endl; for(std::size_t idx = 0; idx < number_of_particles; ++idx) @@ -104,10 +98,10 @@ auto inline check_results(const Tree_T& tree, const Container_T& reference, cons return ok; } -template<int Dimension, class FMM_OPERATOR_TYPE> +template<int Dimension, class FMM_OPERATOR_TYPE, typename TestType> auto run(const std::string& input_file, const int& tree_height, const int& group_size, const int& order) -> int { - using value_type = double; + using value_type = TestType; using near_matrix_kernel_type = typename FMM_OPERATOR_TYPE::near_field_type::matrix_kernel_type; using far_field_type = typename FMM_OPERATOR_TYPE::far_field_type; using interpolator_type = typename far_field_type::approximation_type; @@ -207,10 +201,10 @@ TEMPLATE_TEST_CASE("test fmm", "[test-fmm]", double, float) using matrix_kernel_type = scalfmm::matrix_kernels::others::one_over_r2; using near_field_type = scalfmm::operators::near_field_operator<matrix_kernel_type>; // - using interpolator_type = scalfmm::interpolation::uniform_interpolator<double, dim, matrix_kernel_type>; + using interpolator_type = scalfmm::interpolation::uniform_interpolator<value_type, dim, matrix_kernel_type>; using far_field_type = scalfmm::operators::far_field_operator<interpolator_type>; path.append("test_1d_ref.fma"); - run<1, scalfmm::operators::fmm_operators<near_field_type, far_field_type>>(path, 4, 2, + run<dim, scalfmm::operators::fmm_operators<near_field_type, far_field_type>, value_type>(path, 4, 2, 5); } SECTION("fmm test 2D", "[fmm-test-2D]") @@ -220,10 +214,10 @@ TEMPLATE_TEST_CASE("test fmm", "[test-fmm]", double, float) using matrix_kernel_type = scalfmm::matrix_kernels::others::one_over_r2; using near_field_type = scalfmm::operators::near_field_operator<matrix_kernel_type>; // - using interpolator_type = scalfmm::interpolation::uniform_interpolator<double, dim, matrix_kernel_type>; + using interpolator_type = scalfmm::interpolation::uniform_interpolator<value_type, dim, matrix_kernel_type>; using far_field_type = scalfmm::operators::far_field_operator<interpolator_type>; path.append("test_2d_ref.fma"); - run<1, scalfmm::operators::fmm_operators<near_field_type, far_field_type>>(path, 4, 2, + run<dim, scalfmm::operators::fmm_operators<near_field_type, far_field_type>, value_type>(path, 4, 2, 5); } SECTION("fmm test 3D", "[fmm-test-3D]") @@ -233,10 +227,10 @@ TEMPLATE_TEST_CASE("test fmm", "[test-fmm]", double, float) using matrix_kernel_type = scalfmm::matrix_kernels::others::one_over_r2; using near_field_type = scalfmm::operators::near_field_operator<matrix_kernel_type>; // - using interpolator_type = scalfmm::interpolation::uniform_interpolator<double, dim, matrix_kernel_type>; + using interpolator_type = scalfmm::interpolation::uniform_interpolator<value_type, dim, matrix_kernel_type>; using far_field_type = scalfmm::operators::far_field_operator<interpolator_type>; path.append("test_3d_ref.fma"); - run<1, scalfmm::operators::fmm_operators<near_field_type, far_field_type>>(path, 4, 2, + run<dim, scalfmm::operators::fmm_operators<near_field_type, far_field_type>, value_type>(path, 4, 2, 5); } SECTION("fmm test 4D", "[fmm-test-4D]") @@ -246,10 +240,10 @@ TEMPLATE_TEST_CASE("test fmm", "[test-fmm]", double, float) using matrix_kernel_type = scalfmm::matrix_kernels::others::one_over_r2; using near_field_type = scalfmm::operators::near_field_operator<matrix_kernel_type>; // - using interpolator_type = scalfmm::interpolation::uniform_interpolator<double, dim, matrix_kernel_type>; + using interpolator_type = scalfmm::interpolation::uniform_interpolator<value_type, dim, matrix_kernel_type>; using far_field_type = scalfmm::operators::far_field_operator<interpolator_type>; path.append("test_4d_ref.fma"); - run<1, scalfmm::operators::fmm_operators<near_field_type, far_field_type>>(path, 4, 2, + run<dim, scalfmm::operators::fmm_operators<near_field_type, far_field_type>, value_type>(path, 4, 2, 5); } } diff --git a/experimental/units/fmm/test_non_homogenous.cpp b/experimental/units/fmm/test_non_homogenous.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ef6a7a8baa0e1bf4ee0575db73537a2ba012eab8 --- /dev/null +++ b/experimental/units/fmm/test_non_homogenous.cpp @@ -0,0 +1,257 @@ +// +// Units for test fmm non homogenous +// --------------------------------- +#include "scalfmm/tree/for_each.hpp" +#include "units_fmm.hpp" +#include "scalfmm/algorithms/common.hpp" +#include "scalfmm/container/particle.hpp" +#include "scalfmm/container/particle_container.hpp" +#include "scalfmm/container/point.hpp" +#include "scalfmm/interpolation/uniform.hpp" +#include "scalfmm/operators/fmmOperators.hpp" + +#include "scalfmm/matrix_kernels/debug.hpp" +#include "scalfmm/matrix_kernels/laplace.hpp" +#include "scalfmm/algorithms/sequential/sequential.hpp" + +#include "scalfmm/tools/colorized.hpp" +#include "scalfmm/tree/box.hpp" +#include "scalfmm/tree/cell.hpp" +#include "scalfmm/tree/group_tree.hpp" +#include "scalfmm/tree/leaf.hpp" +#include "scalfmm/utils/sort.hpp" + +#include "scalfmm/tools/fma_loader.hpp" +#include "scalfmm/utils/accurater.hpp" +#include "scalfmm/utils/timer.hpp" + +#include <algorithm> +#include <array> +#include <bits/c++config.h> +#include <chrono> +#include <cstdio> +#include <iostream> +#include <iterator> +#include <sstream> +#include <string> +#include <sys/types.h> +#include <thread> +#include <tuple> +#include <unistd.h> +#include <utility> +#include <vector> + +#define CATCH_CONFIG_RUNNER +#include <catch2/catch.hpp> + +using namespace scalfmm; + +template<int Dimension, typename CONTAINER_T, typename POINT_T, typename VALUE_T> +void read_data(const std::string& filename, CONTAINER_T*& container, POINT_T& Centre, VALUE_T& width) +{ + using particle_type = typename CONTAINER_T::particle_type; + + scalfmm::tools::FFmaGenericLoader<VALUE_T, Dimension> loader(filename); + + const int number_of_particles = loader.getNumberOfParticles(); + width = loader.getBoxWidth(); + Centre = loader.getBoxCenter(); + auto nb_val_to_red_per_part = loader.getNbRecordPerline(); + + VALUE_T* values_to_read = new VALUE_T[nb_val_to_red_per_part]{0}; + container = new CONTAINER_T(number_of_particles); + std::cout << "number_of_particles " << number_of_particles << std::endl; + for(std::size_t idx = 0; idx < number_of_particles; ++idx) + { + loader.fillParticle(values_to_read, nb_val_to_red_per_part); + particle_type p; + std::size_t ii{0}; + for(auto& e: p.position()) + { + e = values_to_read[ii++]; + } + for(auto& e: p.inputs()) + { + e = values_to_read[ii++]; + } + p.variables(values_to_read[ii++], idx); + container->push_particle(idx, p); + } +} +template<typename Tree_T, typename Container_T, typename Value_T> +auto inline check_results(const Tree_T& tree, const Container_T& reference, const Value_T& eps) -> bool +{ + scalfmm::utils::accurater<Value_T> error; + + scalfmm::component::for_each_leaf(std::cbegin(tree), std::cend(tree), [&reference, &error](auto& leaf) { + + const auto& container = leaf.cparticles(); + const auto nb_elt = std::distance(container.begin(), container.end()); + for(std::size_t i = 0; i < nb_elt; ++i) + { + const auto& p = container.particle(i); + const auto& idx = std::get<1>(p.variables()); + error.add(std::get<0>(p.outputs()), std::get<0>(reference.variables(idx))); + } + }); + bool ok = (error.get_relative_l2_norm() < eps); + std::cout << "Error " << error << std::endl; + return ok; +} + +template<typename Tree_T> +auto inline check_equal(const Tree_T& tree, const Tree_T& tree2) -> bool +{ + bool ok{true}; + scalfmm::component::for_each_leaf(std::cbegin(tree), std::cend(tree), std::cbegin(tree2), [&ok](auto const& leaf, auto const& leaf2) + { + auto const& particles = leaf.cparticles(); + auto const& particles2 = leaf2.cparticles(); + const auto nb_elt = std::distance(particles.begin(), particles.end()); + for(std::size_t i = 0; i < nb_elt; ++i) + { + const auto& p = particles.particle(i); + const auto& p2 = particles2.particle(i); + ok &= (std::get<0>(p.outputs()) == std::get<0>(p2.outputs())); + } + } + ); + return ok; +} + +template<int Dimension, class FMM_OPERATOR_TYPE, class FMM_OPERATOR_TYPE2, typename ValueType> +auto run(const std::string& input_file, const int& tree_height, const int& group_size, const int& order) -> bool +{ + using value_type = ValueType; + using near_matrix_kernel_type = typename FMM_OPERATOR_TYPE::near_field_type::matrix_kernel_type; + using far_field_type = typename FMM_OPERATOR_TYPE::far_field_type; + using near_field_type = typename FMM_OPERATOR_TYPE::near_field_type; + using interpolator_type = typename far_field_type::approximation_type; + using near_matrix_kernel_type2 = typename FMM_OPERATOR_TYPE2::near_field_type::matrix_kernel_type; + using far_field_type2 = typename FMM_OPERATOR_TYPE2::far_field_type; + using near_field_type2 = typename FMM_OPERATOR_TYPE2::near_field_type; + using interpolator_type2 = typename far_field_type2::approximation_type; + + using far_matrix_kernel_type = typename interpolator_type::matrix_kernel_type; + using far_matrix_kernel_type2 = typename interpolator_type2::matrix_kernel_type; + // + // + std::cout << scalfmm::colors::blue << "Entering tree test...\n" << scalfmm::colors::reset; + + // The matrix kernel + // + static constexpr std::size_t nb_inputs_near{near_matrix_kernel_type::km}; + static constexpr std::size_t nb_outputs_near{near_matrix_kernel_type::kn}; + static constexpr std::size_t nb_inputs_far{far_matrix_kernel_type::km}; + static constexpr std::size_t nb_outputs_far{far_matrix_kernel_type::kn}; + std::cout << scalfmm::colors::blue << "<params> Runtime order : " << order << scalfmm::colors::reset << '\n'; + + // Open particle file + scalfmm::utils::timer time{}; + + // --------------------------------------- + using particle_type = scalfmm::container::particle<value_type, Dimension, value_type, nb_inputs_near, value_type, + nb_outputs_near, value_type, std::size_t>; + using container_type = scalfmm::container::particle_container<particle_type>; + using position_type = typename particle_type::position_type; + using cell_type = + scalfmm::component::cell<value_type, Dimension, nb_inputs_far, nb_outputs_far, std::complex<value_type>>; + using leaf_type = scalfmm::component::leaf<particle_type>; + using box_type = scalfmm::component::box<position_type>; + using group_tree_type = scalfmm::component::group_tree<cell_type, leaf_type, box_type>; + + std::cout << scalfmm::colors::green << "Creating & Inserting particles ...\n" << scalfmm::colors::reset; + + scalfmm::container::point<value_type, Dimension> box_center{}; + value_type box_width{}; + + time.tic(); + container_type* container{}; + read_data<Dimension>(input_file, container, box_center, box_width); + time.tac(); + + std::cout << scalfmm::colors::green << "... Done.\n" << scalfmm::colors::reset; + std::cout << scalfmm::colors::green << "Box center = " << box_center << " box width = " << box_width + << scalfmm::colors::reset << '\n'; + + std::cout << scalfmm::colors::yellow << "Container loaded in " << time.elapsed() << "ms\n" + << scalfmm::colors::reset; + + time.tic(); + box_type box(box_width, box_center); + group_tree_type tree(static_cast<std::size_t>(tree_height), order, box, static_cast<std::size_t>(group_size), + *container); + group_tree_type tree2(static_cast<std::size_t>(tree_height), order, box, static_cast<std::size_t>(group_size), + *container); + time.tac(); + std::cout << scalfmm::colors::yellow << "Group tree created in " << time.elapsed() << "ms\n" + << scalfmm::colors::reset; + + time.tic(); + far_matrix_kernel_type mk_far{}; + interpolator_type interpolator(mk_far, order, static_cast<std::size_t>(tree_height), box.width(0)); + near_matrix_kernel_type mk_near{}; + near_field_type near_field(mk_near); + far_field_type far_field(interpolator); + FMM_OPERATOR_TYPE fmm_operator(near_field, far_field); + far_matrix_kernel_type2 mk_far2{}; + interpolator_type2 interpolator2(mk_far2, order, static_cast<std::size_t>(tree_height), box.width(0)); + near_matrix_kernel_type2 mk_near2{}; + near_field_type2 near_field2(mk_near2); + far_field_type2 far_field2(interpolator2); + FMM_OPERATOR_TYPE2 fmm_operator2(near_field2, far_field2); + time.tac(); + std::cout << scalfmm::colors::yellow << "Kernel and Interp created in " << time.elapsed() << "ms\n" + << scalfmm::colors::reset; + + auto operator_to_proceed = scalfmm::algorithms::all; + scalfmm::algorithms::sequential(tree, std::move(fmm_operator), operator_to_proceed); + scalfmm::algorithms::sequential(tree2, std::move(fmm_operator2), operator_to_proceed); + value_type eps = std::pow(10.0, 1 - order); + bool works_non_homogenous = check_results(tree, *container, eps); + std::cout << ((works_non_homogenous == true) ? "Non Homogenous passed!\n" : "Non Homogenous failed!\n"); + bool works_homogenous = check_results(tree2, *container, eps); + std::cout << ((works_homogenous == true) ? "Homogenous passed!\n" : "Homogenous failed!\n"); + bool homogenous_eq_non_homogenous = check_equal(tree, tree2); + std::cout << ((homogenous_eq_non_homogenous == true) ? "Homogenous against Non Homogenous passed!\n" : "Homogenous against Non Homogenous failed!\n"); + delete container; + return works_homogenous & works_non_homogenous & homogenous_eq_non_homogenous; +} + + +TEMPLATE_TEST_CASE("test fmm non homogenous", "[test-fmm]", double, float) +{ + using value_type = TestType; + std::string path{TEST_FILES_PATH}; + + SECTION("fmm test non homogenous", "[fmm-test-non_homogenous]") + { + constexpr int dim = 3; + + using matrix_kernel_type = scalfmm::matrix_kernels::debug::one_over_r_non_homogenous; + using matrix_kernel_type2 = scalfmm::matrix_kernels::laplace::one_over_r; + using near_field_type = scalfmm::operators::near_field_operator<matrix_kernel_type>; + using near_field_type2 = scalfmm::operators::near_field_operator<matrix_kernel_type2>; + // + using interpolator_type = scalfmm::interpolation::uniform_interpolator<value_type, dim, matrix_kernel_type>; + using interpolator_type2 = scalfmm::interpolation::uniform_interpolator<value_type, dim, matrix_kernel_type2>; + using far_field_type = scalfmm::operators::far_field_operator<interpolator_type>; + using far_field_type2 = scalfmm::operators::far_field_operator<interpolator_type2>; + path.append("xyzq100_ref.fma"); + REQUIRE(run<dim, scalfmm::operators::fmm_operators<near_field_type, far_field_type>, + scalfmm::operators::fmm_operators<near_field_type2, far_field_type2>, value_type>(path, 4, 2, 5)); + } +} + + +int main(int argc, char* argv[]) +{ + // global setup... + int result = Catch::Session().run(argc, argv); + // global clean-up... + // int result = 0; + // test_l2p<double, 2, 1>(9); + + return result; +} + diff --git a/experimental/units/fmm/xyzq100_ref.fma b/experimental/units/fmm/xyzq100_ref.fma new file mode 100644 index 0000000000000000000000000000000000000000..4af195fb6dd2d02b6229dfaf69d1b0630470226a --- /dev/null +++ b/experimental/units/fmm/xyzq100_ref.fma @@ -0,0 +1,102 @@ +8 5 3 1 +100 0.5 0.5 0.5 0.5 +0.00717844472183415 0.934543986429588 0.0322223347994957 0.396464773760275 61.3170761317188 +0.950688413201483 0.880593979393854 0.304711507385932 0.840485369411425 81.8727655266629 +0.140502847867847 0.0526234894469653 0.182492646147157 0.353336097245244 80.6102843650929 +0.159643730440393 0.0059697732956856 0.0569848010686442 0.446583434796544 68.8668417151561 +0.67522320061197 0.960051698924659 0.737878337808521 0.318692772311881 90.2409618908103 +0.277524543315046 0.298188193905677 0.515409712562388 0.886428433223031 109.454763871254 +0.149195421085505 0.527361281988313 0.881246665792691 0.0155828494083288 87.404626733154 +0.139318619902539 0.691573701834979 0.293013663245937 0.584090220317272 97.3731547457086 +0.114485311016526 0.18957681493913 0.581056807750524 0.159368626531805 90.0078651904238 +0.748215780263799 0.534864987166475 0.970116769109453 0.383715874807194 88.037355817385 +0.365319655214815 0.233134323484755 0.42289790045891 0.691004373382196 114.005783114718 +0.77244481877878 0.691415431464304 0.103511602358658 0.0588589135927364 104.64187471695 +0.768276949612034 0.113278477391859 0.299773895804687 0.899854306161604 87.8521633079526 +0.53996180406758 0.414020340072998 0.624310313199999 0.163545950630365 112.348886093286 +0.730145169875339 0.868314511224163 0.254094513717622 0.159071502581806 101.055671382097 +0.226666990357344 0.0160042624003118 0.686318598431392 0.533064714021855 79.7115879773282 +0.897644485285529 0.0995279757209175 0.856444543834254 0.604144189711239 73.0874400682146 +0.0196052293987421 0.560025648737355 0.967997228386295 0.582699021207219 69.6411754287321 +0.682738563313503 0.380599844522543 0.461052826925741 0.269971117907016 110.51065263633 +0.593784476344297 0.427602296855849 0.908733825957519 0.390478195463409 93.6408823131746 +0.646643598958168 0.273277007153823 0.108959444316891 0.293400570118951 122.759003000587 +0.300126015731898 0.671841563897264 0.116519819692002 0.742377406033981 94.8921469591946 +0.959986065706641 0.451796504890076 0.83969399949304 0.298525606318119 84.3303771735622 +0.89844806436507 0.379867977596941 0.251979170484752 0.0755380785377824 96.9768093544518 +0.85838516297159 0.107032502141919 0.504594230008518 0.404982633583334 87.284398569835 +0.737379374984563 0.613274070016121 0.244032800907021 0.857377942708183 107.845396028407 +0.466934965855895 0.544068121813659 0.834061790468756 0.941968323291899 101.220616289071 +0.510656423420443 0.145331341249129 0.725527843796279 0.662830659789996 90.5424594663154 +0.431350927455373 0.296069207119942 0.311704268203268 0.846475779930007 107.785076004069 +0.264206950742299 0.170616813090849 0.710499054603645 0.00275508142688352 98.9869876758025 +0.950237844089639 0.0174643407788508 0.712468871158354 0.462379245025485 71.7168922735011 +0.111343007391568 0.20820776697752 0.111280349808503 0.532596024438298 77.0405945576327 +0.271549377673981 0.77058192698027 0.98422511536047 0.78787662089292 88.4385722855236 +0.51249113715614 0.706128306546777 0.650902618777181 0.265612234971371 127.234414622641 +0.790296907138522 0.400108345554564 0.548164892124337 0.98275226310103 99.2439260426097 +0.587826068729669 0.926437158635661 0.136679092612987 0.30678513061418 83.9616091863109 +0.699201785775461 0.923069081848681 0.567891052371461 0.600855136489105 93.6130712101018 +0.870412011312958 0.45894404230393 0.973176578867793 0.608715653358658 80.1416030694218 +0.426180604776459 0.727357221382938 0.5068854564113 0.212438798201187 123.671363132055 +0.335629684475791 0.750088214542782 0.970320844115598 0.885895130587606 91.2261075211356 +0.0371367921316939 0.386262090414391 0.578434981334777 0.304657101745793 85.8672910089623 +0.588082032811066 0.645067021647879 0.876630561742516 0.15185986406857 105.557375122807 +0.0432790256488111 0.356151542054754 0.801997626665528 0.337661902873531 79.7598558310246 +0.0333364372345102 0.803275526207141 0.190679663970009 0.387476950965358 76.829570637902 +0.929624128071357 0.244160117701981 0.218850133897686 0.643609828900129 90.9372794065025 +0.45272698092375 0.625836110430928 0.304851401507449 0.753553275640016 112.995822680286 +0.97311113342975 0.994117884407366 0.503049909493246 0.603616098781568 74.0947547963928 +0.327741677172767 0.507758518065199 0.0522932514655778 0.53162825175081 91.0807126688861 +0.212064645761817 0.0768609812762691 0.847460331505271 0.459360316334315 77.8159023066784 +0.374379115602558 0.449935227865712 0.507430338279889 0.652488446971034 117.280150984435 +0.298203526765203 0.0951316810575449 0.328683128419218 0.32718116385065 96.060255555397 +0.229559180031004 0.747058507152001 0.215169670211289 0.946370485960081 95.9442065392026 +0.230219964795015 0.081435558943511 0.187818761775187 0.368039867432817 86.2042827555789 +0.971251826160078 0.837148010253376 0.846604882778678 0.943890339354468 74.2288453489052 +0.927409899866017 0.796214478675729 0.132758529668724 0.00742826171906685 88.041906620622 +0.759067573018555 0.173251237057652 0.910090484357816 0.516599949702389 78.5069699557641 +0.858331091174964 0.950488945553275 0.296468205186937 0.272770952753351 87.8731607647272 +0.234050633278549 0.83162756291232 0.563032294288305 0.024299155634651 98.1746093868572 +0.647690557617917 0.283930837321115 0.125281175201 0.591954502437812 109.505252544952 +0.302050187818764 0.96194993705792 0.879647142218921 0.2049635097516 78.9615677773889 +0.913736625390829 0.673575929015144 0.920856174838971 0.877693349889729 79.6605780003776 +0.940794898516081 0.686759537841088 0.746348539718326 0.0593686933802502 90.2788440106249 +0.590855012170532 0.757842348788621 0.938685477471086 0.260842551926938 92.8169959202498 +0.716707080251538 0.176146087434002 0.00385150199127082 0.302829184161332 80.6508196327986 +0.646027964589624 0.822455158622887 0.717089331685099 0.891495219672155 101.280005638635 +0.345504533226354 0.190444363760282 0.749700689614414 0.49819805913441 94.5279777614266 +0.136095669657234 0.926921131069172 0.546125932789582 0.710025580792159 77.8248263157373 +0.8713208919321 0.942654448217166 0.728485277328424 0.286413993907622 82.8033462063401 +0.785316532036394 0.729314724726024 0.219990620913673 0.86492357739947 107.795625571859 +0.979447948270597 0.345881321633502 0.673736025580894 0.675540671125631 83.8743096425316 +0.443689718480709 0.451849234393883 0.211775027386143 0.458489973232272 113.142712197614 +0.561627083024447 0.646423343408426 0.749348450300111 0.95963556238106 109.73336388174 +0.670156847567316 0.729495820204704 0.314722654478697 0.774675406127844 109.147217025886 +0.183528009582268 0.695148615066092 0.92712674514685 0.376551280801323 86.0666248762068 +0.758777366976172 0.698435234420621 0.163342234862629 0.228639116426205 115.48631225999 +0.649237899416534 0.0628034986316486 0.64845991826207 0.354533877294422 86.4655368022831 +0.003764498102516 0.950669773588615 0.833069752731458 0.300318248151815 64.9699505779116 +0.282653425045247 0.326859943623081 0.772019117148943 0.669765831680721 94.9916105943174 +0.997770360734801 0.158441452428043 0.443038308145663 0.718966572477935 79.9297548836587 +0.443137314841479 0.765276719680397 0.658156371874604 0.56595450872225 118.394471552821 +0.179460089990418 0.0445510935141158 0.355711567134517 0.82446531320608 82.13510844328 +0.462330347765494 0.820134660594039 0.880109325713804 0.390611909814908 95.3003007365252 +0.329213050934438 0.534286293407625 0.443338005815892 0.818766311218223 114.830348880622 +0.402115171135108 0.739762185014552 0.571904206439662 0.844008460045423 114.425626740522 +0.104204377504335 0.502594307036091 0.146231148666796 0.180467770090349 85.7515674230294 +0.305814602154037 0.729615697562625 0.376529106401421 0.943395886088908 105.934640905926 +0.865691997182818 0.680592693188323 0.355837294302621 0.424886765414069 100.99340610094 +0.925831890454887 0.114450919452192 0.199335710376623 0.520665778036708 83.2312749418492 +0.373486276704543 0.423139372602009 0.659312515249251 0.065643754874575 113.121868472118 +0.285465384795749 0.254252378812442 0.424411686518184 0.913508169204363 111.193539088718 +0.807926984130514 0.8024971776914 0.15232824638753 0.882584572720003 94.3436305245195 +0.506664514388859 0.468550931585423 0.147271415526127 0.761364126692378 104.535631432145 +0.211879703615427 0.62542836475545 0.275105018835031 0.398922546078257 107.594070847372 +0.00978812435382537 0.109354341618403 0.81481655552426 0.688256841941055 69.0477745482971 +0.525109222956512 0.778991123594587 0.633371625260043 0.761548303519756 116.384619493317 +0.686119498955421 0.741114346325784 0.114896896559166 0.405008799190391 100.36074588251 +0.100867432747354 0.0789790243648838 0.818946931216271 0.125251137735066 80.4522074684236 +0.740273966253945 0.349713336334123 0.158409273344759 0.484633904711558 100.629610231663 +0.949889209268772 0.507188032585155 0.486953814509466 0.222462553152592 93.427592507731 +0.872821724035816 0.233396458955593 0.1333010335753 0.873121166037272 87.8243657840843