diff --git a/src/CSVWriter/is_csv_writable.hpp b/src/CSVWriter/is_csv_writable.hpp index 556fa9e36c0b77e122833af37426687968591432..b7268b09d9cb62b3f9671c146d06147f1f4cd25a 100644 --- a/src/CSVWriter/is_csv_writable.hpp +++ b/src/CSVWriter/is_csv_writable.hpp @@ -9,111 +9,132 @@ #define OPENFPM_IO_SRC_CSVWRITER_IS_CSV_WRITABLE_HPP_ - +//! Indicate if the property T is writable in CSV template<typename T> struct is_csv_writable { + //! as default if not recognized is not writable enum { value = false }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<float> { + //! float is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<double> { + //! double is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<char> { + //! char is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<unsigned char> { + //! unsigned char is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<short> { + //! short is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<unsigned short> { + //! unsigned is writable enum { value = true }; }; - +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<int> { + //! int is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<unsigned int> { + //! unsigned int is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<long int> { + //! long int is writable enum { value = true }; }; +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<unsigned long int> { + //! unsigned long int is writable enum { value = true }; }; - +//! Indicate if the property T is writable in CSV template<> struct is_csv_writable<bool> { + //! bool is writable enum { value = true diff --git a/src/Plot/GoogleChart.hpp b/src/Plot/GoogleChart.hpp index 1fd659429b63aedfa5529b07ff5dbc3fe4a9fe0c..136e7b228c4ae2c7d9412616079a209d346f2353 100644 --- a/src/Plot/GoogleChart.hpp +++ b/src/Plot/GoogleChart.hpp @@ -75,6 +75,8 @@ struct GCoptions * * \param opt object to copy * + * \return itself + * */ GCoptions & operator=(const GCoptions & opt) { @@ -94,6 +96,9 @@ struct GCoptions } }; +/*! \brief Google Graph + * + */ struct GGraph { //! TypeOfGraph diff --git a/src/VTKWriter/VTKWriter_grids.hpp b/src/VTKWriter/VTKWriter_grids.hpp index b405ce7de55ff5dde1b394c062f05f9e4e273039..46059296bd512cab4ce3d72bd4458ae231b583dc 100644 --- a/src/VTKWriter/VTKWriter_grids.hpp +++ b/src/VTKWriter/VTKWriter_grids.hpp @@ -66,26 +66,40 @@ struct prop_out_g //! File type file_type ft; + //! list of names for the properties + const openfpm::vector<std::string> & prop_names; + /*! \brief constructor * * \param v_out string to fill with the vertex properties * \param vg vector of elements to write + * \param prop_names properties name + * \param ft file type * */ - prop_out_g(std::string & v_out, const openfpm::vector_std< ele_g > & vg, file_type ft) - :v_out(v_out),vg(vg),ft(ft) + prop_out_g(std::string & v_out, const openfpm::vector_std< ele_g > & vg, const openfpm::vector<std::string> & prop_names ,file_type ft) + :v_out(v_out),vg(vg),ft(ft),prop_names(prop_names) {}; - //! It produce an output for each property + /*! It produce an output for each propert + * + * \param t prop-id + * + */ template<typename T> void operator()(T& t) const { typedef typename boost::mpl::at<typename ele_g::value_type::value_type::type,boost::mpl::int_<T::value>>::type ptype; typedef typename std::remove_all_extents<ptype>::type base_ptype; - meta_prop<boost::mpl::int_<T::value> ,ele_g,St, ptype, is_vtk_writable<base_ptype>::value > m(vg,v_out,ft); + meta_prop<boost::mpl::int_<T::value> ,ele_g,St, ptype, is_vtk_writable<base_ptype>::value > m(vg,v_out,prop_names,ft); } + /*! \brief Write the last property + * + * + * + */ void lastProp() { // Create point data properties @@ -191,6 +205,8 @@ class VTKWriter<pair,VECTOR_GRIDS> * * \param ft file type * + * \return the string with the point list + * */ std::string get_point_list(file_type ft) { @@ -303,11 +319,16 @@ public: * * \param file path where to write * \param name of the graph + * \param prop_names properties name (can also be a vector of size 0) * \param ft specify if it is a VTK BINARY or ASCII file [default = ASCII] * + * \return true if the function write successfully + * */ - - template<int prp = -1> bool write(std::string file, std::string f_name = "grids" , file_type ft = file_type::ASCII) + template<int prp = -1> bool write(std::string file, + const openfpm::vector<std::string> & prop_names, + std::string f_name = "grids", + file_type ft = file_type::ASCII) { // Header for the vtk std::string vtk_header; @@ -356,7 +377,7 @@ public: // For each property in the vertex type produce a point data - prop_out_g< ele_g<typename pair::first,typename pair::second>, typename pair::second > pp(point_data, vg, ft); + prop_out_g< ele_g<typename pair::first,typename pair::second>, typename pair::second > pp(point_data, vg, prop_names, ft); if (prp == -1) boost::mpl::for_each< boost::mpl::range_c<int,0, pair::first::value_type::max_prop> >(pp); diff --git a/src/VTKWriter/VTKWriter_grids_util.hpp b/src/VTKWriter/VTKWriter_grids_util.hpp index dcd822729d5eab574a61b5ca01c2b216e1fe6f19..a09f1fa5d6b0ec664d382fe2203094f374782192 100644 --- a/src/VTKWriter/VTKWriter_grids_util.hpp +++ b/src/VTKWriter/VTKWriter_grids_util.hpp @@ -12,7 +12,7 @@ #include "is_vtk_writable.hpp" #include "byteswap_portable.hpp" -/*! \brief Return the Attributes name (if they have) +/*! \brief Return the Attributes name from the type * * */ @@ -23,14 +23,22 @@ struct getAttrName * * \param i id of the attribute * \param oprp post-fix to add + * \param prop_names properties name + * + * \return the string with the property name * */ - static inline std::string get(size_t i, const std::string & oprp) + static inline std::string get(size_t i, const openfpm::vector<std::string> & prop_names, const std::string & oprp) { return ele_g::value_type::value_type::attributes::name[i] + oprp; } }; +/*! \brief Return the Attributes name from the type + * + * This is the case when the type has no name + * + */ template<typename ele_g> struct getAttrName<ele_g,false> { @@ -38,11 +46,21 @@ struct getAttrName<ele_g,false> * * \param i id of the attribute * \param oprp post-fix to add + * \param prop_names properties name + * + * \return return the string with the property name * */ - static inline std::string get(size_t i, const std::string & oprp) + static inline std::string get(size_t i, const openfpm::vector<std::string> & prop_names, const std::string & oprp) { - return std::string("attr" + std::to_string(i) + oprp); + if (i >= prop_names.size()) + { + return std::string("attr" + std::to_string(i) + oprp); + } + else + { + return prop_names.get(i) + oprp; + } } }; @@ -52,7 +70,7 @@ struct getAttrName<ele_g,false> * \param oprp prefix * */ -template<unsigned int i, typename ele_g, bool has_attributes> std::string get_point_property_header_impl(const std::string & oprp) +template<unsigned int i, typename ele_g, bool has_attributes> std::string get_point_property_header_impl(const std::string & oprp, const openfpm::vector<std::string> & prop_names) { //! vertex node output string std::string v_out; @@ -76,7 +94,7 @@ template<unsigned int i, typename ele_g, bool has_attributes> std::string get_po } // Create point data properties - v_out += "VECTORS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n"; + v_out += "VECTORS " + getAttrName<ele_g,has_attributes>::get(i,prop_names,oprp) + " " + type + "\n"; } } else @@ -94,16 +112,16 @@ template<unsigned int i, typename ele_g, bool has_attributes> std::string get_po // We check if it is a vector or scalar like type if (vtk_dims<ctype>::value == 1) - v_out += "SCALARS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n"; + v_out += "SCALARS " + getAttrName<ele_g,has_attributes>::get(i,prop_names,oprp) + " " + type + "\n"; else - v_out += "VECTORS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n"; + v_out += "VECTORS " + getAttrName<ele_g,has_attributes>::get(i,prop_names,oprp) + " " + type + "\n"; } return v_out; } // Create point data properties - v_out += "SCALARS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n"; + v_out += "SCALARS " + getAttrName<ele_g,has_attributes>::get(i,prop_names,oprp) + " " + type + "\n"; // Default lookup table v_out += "LOOKUP_TABLE default\n"; @@ -171,6 +189,15 @@ class prop_write_out<1,T> { public: + /*! \brief Write the property + * + * \param v_out output string of the property + * \param vg vector of properties + * \param k data-set to output + * \param it iterator with the point to output + * \param ft output type BINARY or ASCII + * + */ template<typename vector, typename iterator, typename I> static void write(std::string & v_out, vector & vg, size_t k, iterator & it, file_type ft) { typedef decltype(vg.get(k).g.get_o(it.get()).template get<I::value>()) ctype_; @@ -207,16 +234,17 @@ struct meta_prop * * \param vg array of elements to write * \param v_out string containing the string + * \param prop_names property names * \param ft ASCII or BINARY * */ - inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, file_type ft) + inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, const openfpm::vector<std::string> & prop_names, file_type ft) { // actual string size size_t sz = v_out.size(); // Produce the point properties header - v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>(""); + v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>("",prop_names); // If the output has changed, we have to write the properties if (v_out.size() != sz) @@ -252,16 +280,17 @@ struct meta_prop<I, ele_g,St,T[N1],is_writable> * * \param vg array of elements to write * \param v_out string containing the string + * \param prop_names properties name * \param ft ASCII or BINARY * */ - inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, file_type ft) + inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, const openfpm::vector<std::string> & prop_names , file_type ft) { // actual string size size_t sz = v_out.size(); // Produce the point properties header - v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>(""); + v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>("",prop_names); // If the output has changed, we have to write the properties if (v_out.size() != sz) @@ -327,10 +356,11 @@ struct meta_prop<I, ele_g,St, T[N1][N2],is_writable> * * \param vg array of elements to write * \param v_out string containing the string + * \param prop_names property names * \param ft ASCII or BINARY * */ - inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, file_type ft) + inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, const openfpm::vector<std::string> & prop_names, file_type ft) { for (size_t i1 = 0 ; i1 < N1 ; i1++) { @@ -340,7 +370,7 @@ struct meta_prop<I, ele_g,St, T[N1][N2],is_writable> size_t sz = v_out.size(); // Produce the point properties header - v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>("_" + std::to_string(i1) + "_" + std::to_string(i2)); + v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>("_" + std::to_string(i1) + "_" + std::to_string(i2),prop_names); // If the output has changed, we have to write the properties if (v_out.size() != sz) @@ -387,10 +417,11 @@ struct meta_prop<I,ele_g,St,T,false> * * \param vg array of elements to write * \param v_out string containing the string + * \param prop_names properties name * \param ft ASCII or BINARY * */ - inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, file_type ft) + inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out, const openfpm::vector<std::string> & prop_names, file_type ft) { } }; diff --git a/src/VTKWriter/VTKWriter_point_set.hpp b/src/VTKWriter/VTKWriter_point_set.hpp index 349cccb5a5b927f7809f048be909672518de771e..50a96f46b0f0ec18e382c8393571e9d007d101cf 100644 --- a/src/VTKWriter/VTKWriter_point_set.hpp +++ b/src/VTKWriter/VTKWriter_point_set.hpp @@ -91,6 +91,9 @@ struct prop_out_v //! vector that we are processing const openfpm::vector_std< ele_v > & vv; + //! properties names + const openfpm::vector<std::string> & prop_names; + /*! \brief constructor * * \param v_out string to fill with the vertex properties @@ -98,18 +101,25 @@ struct prop_out_v * \param ft ASCII or BINARY format * */ - prop_out_v(std::string & v_out, const openfpm::vector_std< ele_v > & vv, file_type ft) - :ft(ft),v_out(v_out),vv(vv) + prop_out_v(std::string & v_out, + const openfpm::vector_std< ele_v > & vv, + const openfpm::vector<std::string> & prop_names, + file_type ft) + :ft(ft),v_out(v_out),vv(vv),prop_names(prop_names) {}; - //! It produce an output for each property + /*! \brief It produce an output for each property + * + * \param t property id + * + */ template<typename T> void operator()(T& t) const { typedef typename boost::mpl::at<typename ele_v::value_type::value_type::type,boost::mpl::int_<T::value>>::type ptype; typedef typename std::remove_all_extents<ptype>::type base_ptype; - meta_prop<boost::mpl::int_<T::value> ,ele_v,St, ptype, is_vtk_writable<base_ptype>::value > m(vv,v_out,ft); + meta_prop<boost::mpl::int_<T::value> ,ele_v,St, ptype, is_vtk_writable<base_ptype>::value > m(vv,v_out,prop_names,ft); } void lastProp() @@ -337,11 +347,13 @@ public: * * \param vps vector of positions * \param vpp vector of properties - * \param mark additional information that divide the dataset into 2 - * (in general is used to mark real from ghost information) + * \param mark additional information that divide the dataset into 2 (in general is used to mark real from ghost information) + * \param opt_names optional parameter that indicate the names of the properties * */ - void add(const typename pair::first & vps, const typename pair::second & vpp,size_t mark) + void add(const typename pair::first & vps, + const typename pair::second & vpp, + size_t mark) { ele_vps<typename pair::first> t1(vps,mark); ele_vpp<typename pair::second> t2(vpp,mark); @@ -356,10 +368,16 @@ public: * * \param file path where to write * \param f_name name of the dataset + * \param prop_names properties names * \param ft specify if it is a VTK BINARY or ASCII file [default = ASCII] * + * \return true if the write complete successfully + * */ - template<int prp = -1> bool write(std::string file, std::string f_name = "points" , file_type ft = file_type::ASCII) + template<int prp = -1> bool write(std::string file, + const openfpm::vector<std::string> & prop_names, + std::string f_name = "points" , + file_type ft = file_type::ASCII) { // Header for the vtk std::string vtk_header; @@ -408,7 +426,7 @@ public: // For each property in the vertex type produce a point data - prop_out_v< ele_vpp<typename pair::second>, typename pair::first::value_type::coord_type> pp(point_data, vpp, ft); + prop_out_v< ele_vpp<typename pair::second>, typename pair::first::value_type::coord_type> pp(point_data, vpp, prop_names,ft); if (prp == -1) boost::mpl::for_each< boost::mpl::range_c<int,0, pair::second::value_type::max_prop> >(pp); diff --git a/src/VTKWriter/VTKWriter_unit_tests.hpp b/src/VTKWriter/VTKWriter_unit_tests.hpp index 8d472ebe31af6637bcd62bf0e13244da79462d87..eea17818130ccf7f1eeba8336ccd72926d1a583c 100644 --- a/src/VTKWriter/VTKWriter_unit_tests.hpp +++ b/src/VTKWriter/VTKWriter_unit_tests.hpp @@ -668,7 +668,8 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_grids) vtk_g.add(g3,offset3,spacing3,d3); vtk_g.add(g4,offset4,spacing4,d4); - vtk_g.write("vtk_grids.vtk"); + openfpm::vector<std::string> prp_names; + vtk_g.write("vtk_grids.vtk",prp_names); // Check that match bool test = compare("vtk_grids.vtk","test_data/vtk_grids_test.vtk"); @@ -772,7 +773,8 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_grids) vtk_g.add(g3,offset3,spacing3,d3); vtk_g.add(g4,offset4,spacing4,d4); - vtk_g.write("vtk_grids_prp.vtk"); + openfpm::vector<std::string> prp_names; + vtk_g.write("vtk_grids_prp.vtk",prp_names); // Check that match bool test = compare("vtk_grids_prp.vtk","test_data/vtk_grids_prp_test.vtk"); @@ -821,7 +823,8 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_grids) vtk_g.add(g3,offset3,spacing3,d3); vtk_g.add(g4,offset4,spacing4,d4); - vtk_g.write("vtk_grids_unk.vtk"); + openfpm::vector<std::string> prp_names; + vtk_g.write("vtk_grids_unk.vtk",prp_names); // Check that match bool test = compare("vtk_grids_unk.vtk","test_data/vtk_grids_test.vtk"); @@ -918,7 +921,8 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set ) vtk_v.add(v2ps,v2pp,88); vtk_v.add(v3ps,v3pp,90); - vtk_v.write("vtk_points.vtk"); + openfpm::vector<std::string> prp_names; + vtk_v.write("vtk_points.vtk",prp_names); // Check that match bool test = compare("vtk_points.vtk","test_data/vtk_points_test.vtk"); @@ -929,7 +933,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set ) VTKWriter<boost::mpl::pair<openfpm::vector<Point<3,double>>,openfpm::vector<aggregate<float,Point<3,float>>>>,VECTOR_POINTS> vtk_v2; vtk_v2.add(v1ps,v4pp,75); - vtk_v2.write("vtk_points_pp.vtk"); + vtk_v2.write("vtk_points_pp.vtk",prp_names); // Check that match test = compare("vtk_points_pp.vtk","test_data/vtk_points_pp_test.vtk"); @@ -938,6 +942,53 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set ) } } +BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set_properties ) +{ + Vcluster & v_cl = create_vcluster(); + + if (v_cl.getProcessUnitID() != 0) + return; + + { + // Create 3 vectors with random particles + openfpm::vector<Point<3,double>> v1ps; + openfpm::vector<aggregate<float,float[3]>> v1pp; + + // set the seed + // create the random generator engine + SimpleRNG rng; + + // fill the vector with random data + v1ps.resize(100); + v1pp.resize(100); + + for (size_t i = 0 ; i < v1ps.size(); i++) + { + v1ps.template get<0>(i)[0] = rng.GetUniform(); + v1ps.template get<0>(i)[1] = rng.GetUniform(); + v1ps.template get<0>(i)[2] = rng.GetUniform(); + + + v1pp.template get<0>(i) = rng.GetUniform(); + v1pp.template get<1>(i)[0] = rng.GetUniform(); + v1pp.template get<1>(i)[1] = rng.GetUniform(); + v1pp.template get<1>(i)[2] = rng.GetUniform(); + } + + openfpm::vector<std::string> prop_names; + + // Create a writer and write adding names to the properties + VTKWriter<boost::mpl::pair<openfpm::vector<Point<3,double>>,openfpm::vector<aggregate<float,float[3]>>>,VECTOR_POINTS> vtk_v; + vtk_v.add(v1ps,v1pp,75); + openfpm::vector<std::string> prp_names({"scalar","vector"}); + vtk_v.write("vtk_points_with_prp_names.vtk",prp_names); + + // Check that match + bool test = compare("vtk_points_with_prp_names.vtk","test_data/vtk_points_with_prp_names_test.vtk"); + BOOST_REQUIRE_EQUAL(test,true); + + } +} BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set_binary ) { @@ -1011,8 +1062,9 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set_binary ) vtk_v.add(v2ps,v2pp,88); vtk_v.add(v3ps,v3pp,90); - vtk_v.write("vtk_points_bin.vtk","vtk output",file_type::BINARY); - vtk_v.write("vtk_points_bin2.vtk","vtk output",file_type::BINARY); + openfpm::vector<std::string> prp_names; + vtk_v.write("vtk_points_bin.vtk",prp_names,"vtk output",file_type::BINARY); + vtk_v.write("vtk_points_bin2.vtk",prp_names,"vtk output",file_type::BINARY); // Check that match @@ -1025,7 +1077,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_point_set_binary ) VTKWriter<boost::mpl::pair<openfpm::vector<Point<3,double>>,openfpm::vector<aggregate<float,Point<3,float>>>>,VECTOR_POINTS> vtk_v2; vtk_v2.add(v1ps,v4pp,75); - vtk_v2.write("vtk_points_pp_bin.vtk","vtk output",file_type::BINARY); + vtk_v2.write("vtk_points_pp_bin.vtk",prp_names,"vtk output",file_type::BINARY); // Check that match test = compare("vtk_points_pp_bin.vtk","test_data/vtk_points_pp_bin_test.vtk");