From ac5c47cdd35cebffbd8e15f9cf7053fb383aab35 Mon Sep 17 00:00:00 2001 From: Pietro Incardona <i-bird@localhost.localdomain> Date: Wed, 24 Feb 2016 06:11:00 -0500 Subject: [PATCH] HDF5 Writer compile --- build_io.sh | 1 + configure.ac | 25 +- src/CSVWriter/CSVWriter.hpp | 2 + src/HDF5_XdmfWriter/HDF5_XdmfWriter.hpp | 24 ++ .../HDF5_XdmfWriter_point_set.hpp | 178 +++++++++++ .../HDF5_XdmfWriter_unit_tests.hpp | 64 ++++ src/HDF5_XdmfWriter/HDF5_XdmfWriter_util.hpp | 300 ++++++++++++++++++ src/Makefile.am | 11 +- src/Plot/GoogleChart.hpp | 8 + src/Plot/Plot_unit_tests.hpp | 41 +++ src/Plot/util.hpp | 45 +++ src/VTKWriter/VTKWriter.hpp | 5 +- src/VTKWriter/VTKWriter_graph.hpp | 2 +- src/VTKWriter/VTKWriter_unit_tests.hpp | 8 +- src/main.cpp | 1 + 15 files changed, 702 insertions(+), 13 deletions(-) create mode 100644 src/HDF5_XdmfWriter/HDF5_XdmfWriter.hpp create mode 100644 src/HDF5_XdmfWriter/HDF5_XdmfWriter_point_set.hpp create mode 100644 src/HDF5_XdmfWriter/HDF5_XdmfWriter_unit_tests.hpp create mode 100644 src/HDF5_XdmfWriter/HDF5_XdmfWriter_util.hpp create mode 100644 src/Plot/util.hpp diff --git a/build_io.sh b/build_io.sh index ea5fcd5b..9a30aeb4 100755 --- a/build_io.sh +++ b/build_io.sh @@ -11,6 +11,7 @@ mkdir openfpm_io/src/config git clone git@ppmcore.mpi-cbg.de:incardon/openfpm_devices.git openfpm_devices git clone git@ppmcore.mpi-cbg.de:incardon/openfpm_data.git openfpm_data git clone git@ppmcore.mpi-cbg.de:incardon/openfpm_pdata.git openfpm_pdata +git clone git@ppmcore.mpi-cbg.de:incardon/openfpm_vcluster.git openfpm_vcluster cd "$1/openfpm_io" diff --git a/configure.ac b/configure.ac index 80597d77..7d879ab1 100755 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,18 @@ m4_ifdef([AX_BOOST_IOSTREAMS],,[m4_include([m4/ax_boost_iostreams.m4])]) m4_ifdef([AX_BOOST_PROGRAM_OPTIONS],,[m4_include([m4/ax_boost_program_options.m4])]) m4_ifdef([AX_BOOST_UNIT_TEST_FRAMEWORK],,[m4_include([m4/ax_boost_unit_test_framework.m4])]) -CXXFLAGS+=" --std=c++11 -march=native -mtune=native -Wno-unused-local-typedefs -Wextra -Wno-unused-parameter " +case $host_os in + *cygwin*) + # Do something specific for cygwin + CXXFLAGS+=" --std=gnu++11 " + ;; + *) + #Default Case + CXXFLAGS+=" --std=c++11 " + ;; +esac + +CXXFLAGS+=" -march=native -mtune=native -Wno-unused-local-typedefs -Wextra -Wno-unused-parameter " NVCCFLAGS=" " INCLUDES_PATH=" " @@ -73,9 +84,19 @@ AC_ARG_WITH([pdata], [pdata_dir="$withval"], [pdata_dir="../../openfpm_pdata/src"]) +####### HDF5 + +AX_LIB_HDF5([parallel]) + +if test x"$with_hdf5" = x"no"; then + echo "Cannot detect hdf5, use the --with-hdf5 option if it is not installed in the default location" + exit 207 +fi + + ####### include openfpm_devices include path -INCLUDES_PATH+="-I. -Iconfig -I../../openfpm_data/src -I../../openfpm_devices/src -I$pdata_dir " +INCLUDES_PATH+="-I. -Iconfig -I../../openfpm_vcluster/src -I../../openfpm_data/src -I../../openfpm_devices/src -I$pdata_dir " ######## diff --git a/src/CSVWriter/CSVWriter.hpp b/src/CSVWriter/CSVWriter.hpp index eb90d670..fc6822c8 100644 --- a/src/CSVWriter/CSVWriter.hpp +++ b/src/CSVWriter/CSVWriter.hpp @@ -18,6 +18,8 @@ #include "csv_multiarray.hpp" #include "util.hpp" +#define CSV_WRITER 0x30000 + /*! \brief this class is a functor for "for_each" algorithm * * For each element of the boost::vector the operator() is called. diff --git a/src/HDF5_XdmfWriter/HDF5_XdmfWriter.hpp b/src/HDF5_XdmfWriter/HDF5_XdmfWriter.hpp new file mode 100644 index 00000000..597c69b9 --- /dev/null +++ b/src/HDF5_XdmfWriter/HDF5_XdmfWriter.hpp @@ -0,0 +1,24 @@ +/* + * H5PartWriter.hpp + * + * Created on: Feb 7, 2016 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_HPP_ +#define OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_HPP_ + +#define H5PART_WRITER 0x20000 + +#define H5_POINTSET 1 + +template <unsigned int imp> +class HDF5_XdmfWriter +{ + +}; + +#include "HDF5_XdmfWriter_point_set.hpp" + + +#endif /* OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_HPP_ */ diff --git a/src/HDF5_XdmfWriter/HDF5_XdmfWriter_point_set.hpp b/src/HDF5_XdmfWriter/HDF5_XdmfWriter_point_set.hpp new file mode 100644 index 00000000..fd760158 --- /dev/null +++ b/src/HDF5_XdmfWriter/HDF5_XdmfWriter_point_set.hpp @@ -0,0 +1,178 @@ +/* + * H5PartWriter_point_set.hpp + * + * Created on: Feb 7, 2016 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_POINT_SET_HPP_ +#define OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_POINT_SET_HPP_ + +#include "HDF5_XdmfWriter_util.hpp" +#include "Vector/map_vector.hpp" +#include "VCluster.hpp" + +/*! \brief this class is a functor for "for_each" algorithm + * + * This class is a functor for "for_each" algorithm. For each + * element of the boost::vector the operator() is called. + * Is mainly used to produce write each property in H5Part + * + * \tparam ele_v is the vector of properties + * \tparam seq, sequence of property to output + * \tparam has_name define if the structure define names for the properties + * + */ + +template<typename ele_v, bool has_name> +struct H5_prop_out +{ + // HDF5 file + hid_t file_id; + + // vector that we are processing + ele_v & vv; + + // Up to which element to write + size_t stop; + + /*! \brief constructor + * + * \param v_out string to fill with the vertex properties + * + */ + H5_prop_out(hid_t file_id, ele_v & vv, size_t stop) + :file_id(file_id),vv(vv),stop(stop) + {}; + + //! It produce an output for each property + 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; + + H5_write<ptype,T::value,ele_v>::write(file_id,std::string(ele_v::value_type::attributes::names[T::value]),vv,stop); + } +}; + + + +/*! \brief this class is a functor for "for_each" algorithm + * + * This class is a functor for "for_each" algorithm. For each + * element of the boost::vector the operator() is called. + * Is mainly used to produce an output for each property + * + * \tparam ele_v is the vector of properties + * \tparam seq, sequence of property to output + * \tparam has_name define if the structure define names + * + */ +template<typename ele_v> +struct H5_prop_out<ele_v,false> +{ + // HDF5 file + hid_t file_id; + + // vector that we are processing + ele_v & vv; + + // Up to which element to write + size_t stop; + + /*! \brief constructor + * + * \param v_out string to fill with the vertex properties + * + */ + H5_prop_out(hid_t file_id, ele_v & vv, size_t stop) + :file_id(file_id),vv(vv),stop(stop) + {}; + + //! It produce an output for each property + template<typename T> + void operator()(T& t) const + { + typedef typename boost::mpl::at<typename ele_v::value_type::type,boost::mpl::int_<T::value>>::type ptype; + + H5_write<ptype,T::value,ele_v>::write(file_id,std::string("attr") + std::to_string(T::value),vv,stop); + } +}; + +template <> +class HDF5_XdmfWriter<H5_POINTSET> +{ + // Time step + int t; + + //! HDF5 file + hid_t file_id; + +public: + + /*! + * + * H5PartWriter constructor + * + */ + HDF5_XdmfWriter() + :t(0) + {} + + + /*! + * + * \brief Write a set of particle position and properties into HDF5 + * + * \tparam Pos Vector of positions type + * \taparam Prp Vector of properties type + * \tparam prp list of properties to output + * + * \param pos Vector with the positions + * \param prp Vector with the properties + * \param stop size of the vector to output + * + */ + template<typename VPos, typename VPrp, int ... prp > bool write(const std::string & file, openfpm::vector<VPos> & v_pos, openfpm::vector<VPrp> & v_prp, size_t stop) + { + Vcluster & v_cl = *global_v_cluster; + + // Open and HDF5 file in parallel + + hid_t plist_id = H5Pcreate(H5P_FILE_ACCESS); + H5Pset_fapl_mpio(plist_id, v_cl.getMPIComm(), MPI_INFO_NULL); + file_id = H5Fcreate(file.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, plist_id); + H5Pclose(plist_id); + + // Single coordinate positional vector + openfpm::vector<typename VPos::coord_type> x_n; + x_n.resize(stop); + + //for each component, fill x_n + for (size_t i = 0 ; i < VPos::dims ; i++) + { + // + for (size_t j = 0 ; j < stop ; j++) + x_n.get(j) = v_pos.template get<0>(j)[i]; + + std::stringstream str; + str << "x" << i; + + HDF5CreateDataSet<typename VPos::coord_type>(file_id,str.str(),x_n.getPointer(),stop*sizeof(typename VPos::coord_type)); + } + + // Now we write the properties + + typedef typename to_boost_vmpl<prp ... >::type v_prp_seq; + H5_prop_out<openfpm::vector<VPrp>,has_attributes<VPrp>::value> f(file_id,v_prp,stop); + + boost::mpl::for_each_ref<v_prp_seq>(f); + + H5Fclose(file_id); + + return true; + } +}; + + +#endif /* OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_POINT_SET_HPP_ */ diff --git a/src/HDF5_XdmfWriter/HDF5_XdmfWriter_unit_tests.hpp b/src/HDF5_XdmfWriter/HDF5_XdmfWriter_unit_tests.hpp new file mode 100644 index 00000000..86bd879f --- /dev/null +++ b/src/HDF5_XdmfWriter/HDF5_XdmfWriter_unit_tests.hpp @@ -0,0 +1,64 @@ +/* + * H5PartWriter_unit_tests.hpp + * + * Created on: Feb 22, 2016 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_UNIT_TESTS_HPP_ +#define OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_UNIT_TESTS_HPP_ + +#include "VCluster.hpp" +#include "util/SimpleRNG.hpp" +#include "HDF5_XdmfWriter.hpp" + +BOOST_AUTO_TEST_SUITE( HDF5_writer_test ) + + +BOOST_AUTO_TEST_CASE( HDF5_writer_use) +{ + openfpm::vector<Point<3,double>> pv; + openfpm::vector<Point_test<double>> pvp; + + SimpleRNG rng; + + Vcluster & v_cl = *global_v_cluster; + + if (v_cl.getProcessingUnits() != 3) + return; + + double z_base = v_cl.getProcessUnitID(); + + // fill 1000 particles for each processors + + for (size_t i = 0 ; i < 1000 ; i++) + { + Point<3,double> p; + p[0] = rng.GetUniform(); + p[1] = rng.GetUniform(); + p[2] = z_base+rng.GetUniform(); + + pv.add(p); + + p[0] += 2.0; + + Point_test<double> pt; + pt.fill(); + + pvp.add(pt); + } + + HDF5_XdmfWriter<H5_POINTSET> h5p; + h5p.template write<Point<3,double>,Point_test<double>,0,1,4,5>("h5part.h5",pv,pvp,1000); + + // check that match + + bool test = compare("test_h5part.h5part","test_h5part_test.h5part"); + BOOST_REQUIRE_EQUAL(true,test); +} + +BOOST_AUTO_TEST_SUITE_END() + + + +#endif /* OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_UNIT_TESTS_HPP_ */ diff --git a/src/HDF5_XdmfWriter/HDF5_XdmfWriter_util.hpp b/src/HDF5_XdmfWriter/HDF5_XdmfWriter_util.hpp new file mode 100644 index 00000000..db7acd59 --- /dev/null +++ b/src/HDF5_XdmfWriter/HDF5_XdmfWriter_util.hpp @@ -0,0 +1,300 @@ +/* + * H5PartWriteData_meta.hpp + * + * Created on: Feb 22, 2016 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_UTIL_HPP_ +#define OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_UTIL_HPP_ + +#include "hdf5.h" +#include "Vector/map_vector.hpp" + +/*! \brief HDF5 Create the data-set in the file + * + * \tparam type Type to write + * + * \param file_id Id of the file + * \param filespace id where to write + * \param str dataset to write + * \param ptr pointer with the data to write + * \param sz size of the data to write + * + * \return true if the function succeed + * + */ +template<typename type> bool HDF5CreateDataSet(hid_t file_id, const std::string & str ,void * ptr, size_t sz) +{ + hid_t plist_id = H5Pcreate(H5P_DATASET_XFER); + if (plist_id < 0) + return false; + + /* Create the dataspace for the position dataset. */ + hsize_t dimsf[1] = {sz}; + hid_t filespace = H5Screate_simple(1, dimsf, NULL); + if (filespace < 0) + return false; + + if (std::is_same<type,char>::value == true) + { + hid_t dset_id = H5Dcreate(file_id, str.c_str(), H5T_NATIVE_CHAR, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (dset_id < 0) + return false; + + herr_t status = H5Dwrite(dset_id, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL, plist_id, ptr); + if (status < 0) + return false; + + H5Dclose(dset_id); + H5Dclose(filespace); + return true; + } +/* else if (std::is_same<type,signed char>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_SCHAR, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + H5Dclose(dset_id); + return status; + } + else if (std::is_same<type,unsigned char>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_UCHAR, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + else if (std::is_same<type,short>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_SHORT, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + else if (std::is_same<type,unsigned short>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_USHORT, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + else if (std::is_same<type,int>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_INT, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + else if (std::is_same<type,unsigned int>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_UINT, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + else if (std::is_same<type,long>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_LONG, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + else if (std::is_same<type,unsigned long>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_ULONG, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + else if (std::is_same<type,long long>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_LLONG, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + else if (std::is_same<type,unsigned long long>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_ULLONG, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + else if (std::is_same<type,float>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_FLOAT, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + }*/ + else if (std::is_same<type,double>::value == true) + { + hid_t dset_id = H5Dcreate(file_id, str.c_str(), H5T_NATIVE_DOUBLE, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + if (dset_id < 0) + return false; + + herr_t status = H5Dwrite(dset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, plist_id, ptr); + if (status < 0) + return false; + + H5Dclose(dset_id); + H5Dclose(filespace); + return true; + } + /*else if (std::is_same<type,long double>::value == true) + { + dset_id = H5Dcreate(file_id, std.c_str(), H5T_NATIVE_LDOUBLE, filespace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + }*/ + + return true; +} + + +/*! \brief Write an HDF5 dataset in case of scalars and vectors + * + * \tparam T type to write + * \tparam pid Property id + * \tparam V Vector containing the information + * + */ +template<typename T,size_t pid, typename V> +struct H5_write +{ + /*! \brief write + * + * \param file_id HDF5 file + * \param str dataset name + * \param v Vector containing the information + * \param stop size to store + * + */ + static inline void write(hid_t file_id, const std::string & str, V & v, size_t stop) + { + // Create the buffer + openfpm::vector<T> buffer; + buffer.resize(stop); + + for (size_t j = 0 ; j < stop ; j++) + buffer.get(j) = v.template get<pid>(j); + + HDF5CreateDataSet<T>(file_id,str.c_str(),buffer.getPointer(),stop*sizeof(T)); + } +}; + +//! Partial specialization for N=1 1D-Array +template<typename T,size_t pid, typename V,size_t N1> +struct H5_write<T[N1],pid,V> +{ + + /*! \brief write + * + * \param file_id HDF5 file + * \param str dataset name + * \param v Vector containing the information + * \param stop size to store + * + */ + static inline void write(hid_t file_id, const std::string & str, V & v, size_t stop) + { + for (size_t i1 = 0 ; i1 < N1 ; i1++) + { + // Create the buffer + openfpm::vector<T> buffer; + buffer.resize(stop); + + for (size_t j = 0 ; j < stop ; j++) + buffer.get(j) = v.template get<pid>(j)[i1]; + + std::stringstream sstr; + sstr << "_" << i1; + + HDF5CreateDataSet<T>(file_id,std::string(str) + sstr.str(),v.getPointer(),stop*sizeof(T)); + } + } +}; + +//! Partial specialization for N=2 2D-Array +template<typename T, size_t pid, typename V,size_t N1,size_t N2> +struct H5_write<T[N1][N2],pid,V> +{ + + /*! \brief write + * + * \param file_id HDF5 file + * \param str dataset name + * \param v Vector containing the information + * \param stop size to store + * + */ + static inline void write(hid_t file_id, const std::string & str, V & v, size_t stop) + { + for (size_t i1 = 0 ; i1 < N1 ; i1++) + { + for (size_t i2 = 0 ; i2 < N2 ; i2++) + { + // Create the buffer + openfpm::vector<T> buffer; + buffer.resize(stop); + + for (size_t j = 0 ; j < stop ; j++) + buffer.get(j) = v.template get<pid>(j)[i1][i2]; + + std::stringstream sstr; + sstr << "_" << i1 << "_" << i2; + + HDF5CreateDataSet<T>(file_id,std::string(str) + sstr.str(),v.getPointer(),stop*sizeof(T)); + } + } + } +}; + +//! Partial specialization for N=3 +template<typename T, size_t pid, typename V,size_t N1,size_t N2,size_t N3> +struct H5_write<T[N1][N2][N3],pid,V> +{ + + /*! \brief write + * + * \param file_id HDF5 file + * \param str dataset name + * \param v Vector containing the information + * \param stop size to store + * + */ + static inline void write(hid_t file_id, const std::string & str, V & v, size_t stop) + { + for (size_t i1 = 0 ; i1 < N1 ; i1++) + { + for (size_t i2 = 0 ; i2 < N2 ; i2++) + { + for (size_t i3 = 0 ; i3 < N3 ; i3++) + { + // Create the buffer + openfpm::vector<T> buffer; + buffer.resize(stop); + + for (size_t j = 0 ; j < stop ; j++) + buffer.get(j) = v.template get<pid>(j)[i1][i2][i3]; + + std::stringstream sstr; + sstr << "_" << i1 << "_" << i2 << "_" << i3; + + HDF5CreateDataSet<T>(file_id,std::string(str) + sstr.str(),v.getPointer(),stop*sizeof(T)); + } + } + } + } +}; + +//! Partial specialization for N=4 +template<typename T, size_t pid, typename V ,size_t N1,size_t N2,size_t N3,size_t N4> +struct H5_write<T[N1][N2][N3][N4],pid,V> +{ + + /*! \brief write + * + * \param file_id HDF5 file + * \param str dataset name + * \param v Vector containing the information + * \param stop size to store + * + */ + static inline void write(hid_t file_id, const std::string & str, V & v, size_t stop) + { + for (size_t i1 = 0 ; i1 < N1 ; i1++) + { + for (size_t i2 = 0 ; i2 < N2 ; i2++) + { + for (size_t i3 = 0 ; i3 < N3 ; i3++) + { + for (size_t i4 = 0 ; i4 < N4 ; i4++) + { + // Create the buffer + openfpm::vector<T> buffer; + buffer.resize(stop); + + for (size_t j = 0 ; j < stop ; j++) + buffer.get(j) = v.template get<pid>(j)[i1][i2][i3][i4]; + + + std::stringstream sstr; + sstr << "_" << i1 << "_" << i2 << "_" << i3 << "_" << i4; + + HDF5CreateDataSet<T>(file_id,std::string(str) + sstr.str(),v.getPointer(),stop*sizeof(T)); + } + } + } + } + } +}; + +#endif /* OPENFPM_IO_SRC_HDF5_XDMFWRITER_HDF5_XDMFWRITER_UTIL_HPP_ */ diff --git a/src/Makefile.am b/src/Makefile.am index 49b06a96..a51c04f2 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,13 +1,16 @@ -LINKLIBS = $(PTHREAD_LIBS) $(OPT_LIBS) $(BOOST_IOSTREAMS_LIB) $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) $(BOOST_THREAD_LIB) +LINKLIBS = $(PTHREAD_LIBS) $(OPT_LIBS) $(BOOST_IOSTREAMS_LIB) $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) $(BOOST_THREAD_LIB) $(HDF5_LDFLAGS) $(HDF5_LIBS) noinst_PROGRAMS = io -io_SOURCES = main.cpp ../../openfpm_devices/src/memory/HeapMemory.cpp ../../openfpm_devices/src/Memleak_check.cpp -io_CXXFLAGS = $(CUDA_CFLAGS) $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include +io_SOURCES = main.cpp ../../openfpm_vcluster/src/VCluster.cpp ../../openfpm_devices/src/memory/HeapMemory.cpp ../../openfpm_devices/src/Memleak_check.cpp +io_CXXFLAGS = $(CUDA_CFLAGS) $(INCLUDES_PATH) $(BOOST_CPPFLAGS) -I/usr/local/include $(HDF5_CPPFLAGS) io_CFLAGS = $(CUDA_CFLAGS) io_LDADD = $(LINKLIBS) -nobase_include_HEADERS = CSVWriter/csv_multiarray.hpp CSVWriter/CSVWriter.hpp GraphMLWriter/GraphMLWriter.hpp util.hpp VTKWriter/VTKWriter.hpp VTKWriter/VTKWriter_graph.hpp VTKWriter/VTKWriter_grids.hpp VTKWriter/VTKWriter_grids_st.hpp VTKWriter/VTKWriter_grids_util.hpp VTKWriter/VTKWriter_vector_box.hpp +nobase_include_HEADERS = CSVWriter/csv_multiarray.hpp CSVWriter/CSVWriter.hpp \ +GraphMLWriter/GraphMLWriter.hpp util.hpp \ +VTKWriter/VTKWriter.hpp VTKWriter/VTKWriter_graph.hpp VTKWriter/VTKWriter_point_set.hpp VTKWriter/VTKWriter_grids.hpp VTKWriter/VTKWriter_grids_st.hpp VTKWriter/VTKWriter_grids_util.hpp VTKWriter/VTKWriter_vector_box.hpp HDF5_XdmfWriter/HDF5_XdmfWriter.hpp HDF5_XdmfWriter/HDF5_XdmfWriter_point_set.hpp HDF5_XdmfWriter/HDF5_XdmfWriter_util.hpp \ +Plot/GoogleChart.hpp Plot/util.hpp .cu.o : diff --git a/src/Plot/GoogleChart.hpp b/src/Plot/GoogleChart.hpp index 105ac735..1bf4a081 100644 --- a/src/Plot/GoogleChart.hpp +++ b/src/Plot/GoogleChart.hpp @@ -9,6 +9,7 @@ #define OPENFPM_DATA_SRC_PLOT_GOOGLECHART_HPP_ #include <fstream> +#include "Vector/map_vector.hpp" #define GGRAPH_COLUMS 1 #define GGRAPH_POINTS 2 @@ -54,6 +55,9 @@ struct GCoptions //! Check Google Chart API interval option std::string intervalext; + //! more + std::string more; + GCoptions & operator=(const GCoptions & opt) { title = opt.title; @@ -66,6 +70,7 @@ struct GCoptions lineWidth = opt.lineWidth; intervalsext = opt.intervalsext; + more = opt.more; return *this; } @@ -232,6 +237,7 @@ class GoogleChart str << "seriesType: '" << opt.stype << "',\n"; if (opt.stypeext.size() != 0) str << "series: " << opt.stypeext << "\n"; + str << opt.more; return str.str(); } @@ -253,6 +259,8 @@ class GoogleChart if (opt.intervalext.size() != 0) str << "interval: " << opt.intervalext << "\n"; + str << opt.more; + return str.str(); } diff --git a/src/Plot/Plot_unit_tests.hpp b/src/Plot/Plot_unit_tests.hpp index f3df91bb..7c77f192 100644 --- a/src/Plot/Plot_unit_tests.hpp +++ b/src/Plot/Plot_unit_tests.hpp @@ -9,6 +9,7 @@ #define OPENFPM_DATA_SRC_PLOT_PLOT_UNIT_TESTS_HPP_ #include "GoogleChart.hpp" +#include "Plot/util.hpp" BOOST_AUTO_TEST_SUITE( plot_unit_test ) @@ -382,6 +383,46 @@ BOOST_AUTO_TEST_CASE( google_chart_linear_plot2 ) BOOST_REQUIRE_EQUAL(true,test); } +//! [Definition of a function] + +double f(double x) +{ + return x*x; +} + +//! [Definition of a function] + +BOOST_AUTO_TEST_CASE( plot_util ) +{ + //! [fill a vector] + + openfpm::vector<double> x; + + Fill1D(0.0,2.0,5,x); + + BOOST_REQUIRE_EQUAL(x.get(0),0.0); + BOOST_REQUIRE_EQUAL(x.get(1),0.5); + BOOST_REQUIRE_EQUAL(x.get(2),1.0); + BOOST_REQUIRE_EQUAL(x.get(3),1.5); + BOOST_REQUIRE_EQUAL(x.get(4),2.0); + + //! [fill a vector] + + x.clear(); + + //! [fill a vector with a function] + + Fill1D(0.0,2.0,5,x,f); + + BOOST_REQUIRE_EQUAL(x.get(0),0.0); + BOOST_REQUIRE_EQUAL(x.get(1),0.25); + BOOST_REQUIRE_EQUAL(x.get(2),1.0); + BOOST_REQUIRE_EQUAL(x.get(3),2.25); + BOOST_REQUIRE_EQUAL(x.get(4),4.0); + + //! [fill a vector function] +} + BOOST_AUTO_TEST_SUITE_END() #endif /* OPENFPM_DATA_SRC_PLOT_PLOT_UNIT_TESTS_HPP_ */ diff --git a/src/Plot/util.hpp b/src/Plot/util.hpp new file mode 100644 index 00000000..b9a53c52 --- /dev/null +++ b/src/Plot/util.hpp @@ -0,0 +1,45 @@ +/* + * util.hpp + * + * Created on: Feb 23, 2016 + * Author: i-bird + */ + +#ifndef OPENFPM_IO_SRC_PLOT_UTIL_HPP_ +#define OPENFPM_IO_SRC_PLOT_UTIL_HPP_ + +/*! \brief It fill the vector x with function values + * + * ### Define a function + * \snippet Plot_unit_tests.hpp Definition of a function + * ### Example vector with points on a specified range + * \snippet Plot_unit_tests.hpp fill a vector with a function + * + */ +template<typename T> static inline void Fill1D(T start, T stop, size_t np, openfpm::vector<T> & x,T f(T x)) +{ + x.resize(np); + + T spacing = (stop - start) / (np - 1); + + for (size_t i = 0 ; i < np ; i++) + x.get(i) = f(start + i*spacing); +} + +/*! \brief It fill the vector x with uniformly distributed set of points + * + * ### Example vector with points on a specified range + * \snippet Plot_unit_tests.hpp fill a vector + * + */ +template<typename T> static inline void Fill1D(T start, T stop, size_t np, openfpm::vector<T> & x) +{ + x.resize(np); + + T spacing = (stop - start) / (np - 1); + + for (size_t i = 0 ; i < np ; i++) + x.get(i) = start + i*spacing; +} + +#endif /* OPENFPM_IO_SRC_PLOT_UTIL_HPP_ */ diff --git a/src/VTKWriter/VTKWriter.hpp b/src/VTKWriter/VTKWriter.hpp index 945dd03d..9567ca75 100644 --- a/src/VTKWriter/VTKWriter.hpp +++ b/src/VTKWriter/VTKWriter.hpp @@ -94,13 +94,14 @@ enum file_type ASCII }; -#define GRAPH 1 +#define VTK_GRAPH 1 #define VECTOR_BOX 2 #define VECTOR_GRIDS 3 #define VECTOR_ST_GRIDS 4 #define VECTOR_POINTS 5 +#define VTK_WRITER 0x10000 -template <typename Graph, unsigned int imp> +template <typename Object, unsigned int imp> class VTKWriter { diff --git a/src/VTKWriter/VTKWriter_graph.hpp b/src/VTKWriter/VTKWriter_graph.hpp index 8d57105e..be7706a5 100644 --- a/src/VTKWriter/VTKWriter_graph.hpp +++ b/src/VTKWriter/VTKWriter_graph.hpp @@ -878,7 +878,7 @@ struct prop_out_edge */ template<typename Graph> -class VTKWriter<Graph, GRAPH> +class VTKWriter<Graph, VTK_GRAPH> { const Graph & g; diff --git a/src/VTKWriter/VTKWriter_unit_tests.hpp b/src/VTKWriter/VTKWriter_unit_tests.hpp index dd7235e8..09dc9cab 100644 --- a/src/VTKWriter/VTKWriter_unit_tests.hpp +++ b/src/VTKWriter/VTKWriter_unit_tests.hpp @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_graph3D ) // Write the VTK file - VTKWriter<Graph_CSR<vertex2,edge>,GRAPH> vtk(gr); + VTKWriter<Graph_CSR<vertex2,edge>,VTK_GRAPH> vtk(gr); vtk.write("vtk_graph_v2.vtk"); // check that match @@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_graph3D_edge ) // Write the VTK file - VTKWriter<Graph_CSR<vertex2,vertex2>,GRAPH> vtk(gr); + VTKWriter<Graph_CSR<vertex2,vertex2>,VTK_GRAPH> vtk(gr); vtk.write("vtk_graph_v4.vtk"); // check that match @@ -363,7 +363,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_graph2D ) // Write the VTK file - VTKWriter<Graph_CSR<vertex3,edge>,GRAPH> vtk(gr); + VTKWriter<Graph_CSR<vertex3,edge>,VTK_GRAPH> vtk(gr); vtk.write("vtk_graph_v3.vtk"); // check that match @@ -443,7 +443,7 @@ BOOST_AUTO_TEST_CASE( vtk_writer_use_graph) // Write the VTK file - VTKWriter<Graph_CSR<vertex,edge>,GRAPH> vtk(gr); + VTKWriter<Graph_CSR<vertex,edge>,VTK_GRAPH> vtk(gr); vtk.write("vtk_graph.vtk"); // check that match diff --git a/src/main.cpp b/src/main.cpp index d36a713f..9e6ada39 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -9,4 +9,5 @@ #include "CSVWriter/CSVWriter_unit_tests.hpp" #include "GraphMLWriter/GraphMLWriter_unit_tests.hpp" #include "VTKWriter/VTKWriter_unit_tests.hpp" +#include "HDF5_XdmfWriter/HDF5_XdmfWriter_unit_tests.hpp" #include "Plot/Plot_unit_tests.hpp" -- GitLab