diff --git a/include/scalfmm/meta/utils.hpp b/include/scalfmm/meta/utils.hpp index 64ef4cf1537626843794dc3666595f111faad593..1c11fea7e359002f601a4e3c45e60a76583efd0a 100644 --- a/include/scalfmm/meta/utils.hpp +++ b/include/scalfmm/meta/utils.hpp @@ -209,7 +209,7 @@ namespace scalfmm::meta }; /** - * @brief + * @brief return the size of the tuple * * @tparam T */ @@ -335,6 +335,24 @@ namespace scalfmm::meta { }; + /** + * @brief contains the size of a patricle type without the vatiables + * + * use particle_size_without_variables<ParticleType>::size ; + * @tparam PositionType + * @tparam PositionDim + * @tparam InputsType + * @tparam NInputs + * @tparam OutputsType + * @tparam MOutputs + * @tparam Variables + */ + template<typename ParticleType> + struct particle_size_without_variables + { + static constexpr size_t size = ParticleType::dimension + ParticleType::inputs_size + ParticleType::outputs_size; + }; + /** * @brief * diff --git a/include/scalfmm/tools/fma_loader.hpp b/include/scalfmm/tools/fma_loader.hpp index 6021822b1a0af9494da72d394c66d65ee1fdc339..9957b745cf1d0e3c9ef3dc4ebf07a25e7cd233c7 100644 --- a/include/scalfmm/tools/fma_loader.hpp +++ b/include/scalfmm/tools/fma_loader.hpp @@ -730,10 +730,10 @@ namespace scalfmm::io } std::cout << std::endl << std::flush; } - template<typename IntType1, typename IntType2> - auto writeHeader(const FReal* centerOfBox, const FReal& boxWidth, const IntType1& nbParticles, - const IntType2& dataType, const IntType2& nbDataPerRecord, const IntType2& dimension, - const IntType2& nb_input_values) -> void + < template<typename IntType1, typename IntType2> + auto writeHeader(const FReal* centerOfBox, const FReal& boxWidth, const IntType1& nbParticles, + const IntType2& dataType, const IntType2& nbDataPerRecord, const IntType2& dimension, + const IntType2& nb_input_values) -> void { std::array<unsigned int, 4> typeFReal = { static_cast<unsigned int>(dataType), static_cast<unsigned int>(nbDataPerRecord), @@ -916,8 +916,8 @@ namespace scalfmm::io * @tparam ContainerType * @tparam PointType * @tparam ValueType - * @param values - * @param number_particles + * @param values the contnaire of particles + * @param number_particles. number of particles to write * @param center * @param box_width */ @@ -938,6 +938,8 @@ namespace scalfmm::io using particles_t = std::array<data_type, nb_elt_per_par>; std::vector<particles_t> particles(number_particles); + std::cout << " WRONG \n"; + #pragma omp parallel for shared(particles) for(auto it_p = std::begin(values); it_p < std::end(values); ++it_p) { @@ -955,6 +957,89 @@ namespace scalfmm::io nb_elt_per_par, dimension, nb_input_per_par); this->writeArrayOfReal(particles.data()->data(), nb_elt_per_par, number_particles); } + /** + * @brief + * + * writeDataFrom write all data from the std::vector of particles in fma format + * + * How to get automatically double from container + * + * @tparam ContainerType + * @tparam PointType + * @tparam ValueType + * @param values the vector of particles + * @param center the center of the box + * @param box_width th width of the box + */ + template<class ParticleType, class PointType, typename ValueType> + auto writeDataFrom(std::vector<ParticleType>& values, const PointType& center, const ValueType box_width) + -> void + { + // get the number of elements per particles in the container build with tuples. + using particle_type = ParticleType; + static constexpr std::size_t dimension = particle_type::dimension_size; + static constexpr std::size_t outputs_size = particle_type::outputs_size; + static constexpr std::size_t inputs_size = particle_type::inputs_size; + constexpr std::size_t nb_elt_per_par = scalfmm::meta ::particle_size_without_variables<particle_type>::size; + /// @todo check for different input and output types (double versus complexe) + using data_type = typename particle_type::outputs_value_type; + using particles_t = std::array<data_type, nb_elt_per_par>; + // Not good output_values are put in input_values + constexpr std::size_t nb_input_per_par = particle_type::inputs_size; + + auto number_particles = values.size(); + // if constexpr(nb_elt_per_par < scalfmm::meta ::tuple_size_v<particle_type>) + if constexpr(sizeof(particle_type) > nb_elt_per_par * sizeof(ValueType)) + // + { + // std::cout << " I have variables\n"; + std::vector<particles_t> particles(number_particles); +#pragma omp parallel for shared(particles, values) + for(std::size_t i = 0; i < values.size(); ++i) + { + particle_type& p = values[i]; + particles_t& a = particles[i]; + int k{0}; + + for(auto e: p.position()) + { + a[k++] = e; + } + for(auto& e: p.inputs()) + { + a[k++] = e; + } + for(auto& e: p.outputs()) + { + a[k++] = e; + } + } + // write the particles + // Here we need to separate input from output variables - no tools yet + this->writeHeader(center, box_width, number_particles, static_cast<std::size_t>(sizeof(data_type)), + nb_elt_per_par, dimension, nb_input_per_par); + this->writeArrayOfReal(particles.data()->data(), nb_elt_per_par, number_particles); + } + else + { + // std::cout << nb_elt_per_par << " . " << scalfmm::meta ::tuple_size_v<particle_type> << std::endl; + this->writeHeader(center, box_width, number_particles, static_cast<std::size_t>(sizeof(data_type)), + nb_elt_per_par, dimension, nb_input_per_par); + // std::cout << " " << &(values[0].position()[0]) << " " << values.data() << std::endl; + auto ptr_data = &(values[0].position()[0]); + // int k{0}; + // for(int i = 0; i < 3; ++i) + // { + // std::cout << i << " part " << values[i] << " array "; + // for(int j = 0; j < nb_elt_per_par; ++j, ++k) + // { + // std::cout << ptr_data[k] << " "; + // } + // std::cout << std::endl; + // } + this->writeArrayOfReal(ptr_data, nb_elt_per_par, number_particles); + } + } protected: /**