VTKWriter_grids_util.hpp 9.22 KB
Newer Older
incardon's avatar
incardon committed
1 2 3 4
/*
 * VTKWriter_grids_util.hpp
 *
 *  Created on: Aug 10, 2015
5
 *      Author: Pietro Incardona
incardon's avatar
incardon committed
6 7 8 9 10
 */

#ifndef SRC_VTKWRITER_GRIDS_UTIL_HPP_
#define SRC_VTKWRITER_GRIDS_UTIL_HPP_

11
#include "util/util_debug.hpp"
Pietro Incardona's avatar
Pietro Incardona committed
12
#include "is_vtk_writable.hpp"
13

Pietro Incardona's avatar
Pietro Incardona committed
14
/*! \brief Return the Attributes name (if they have)
incardon's avatar
incardon committed
15 16 17
 *
 *
 */
Pietro Incardona's avatar
Pietro Incardona committed
18 19
template<typename ele_g, bool has_attributes>
struct getAttrName
incardon's avatar
incardon committed
20
{
Pietro Incardona's avatar
Pietro Incardona committed
21 22 23 24 25 26 27 28 29 30 31
	/*! \brief Get attribute name
	 *
	 * \param i id of the attribute
	 * \param oprp post-fix to add
	 *
	 */
	static inline std::string get(size_t i, const std::string & oprp)
	{
		return ele_g::value_type::value_type::attributes::name[i] + oprp;
	}
};
incardon's avatar
incardon committed
32

Pietro Incardona's avatar
Pietro Incardona committed
33 34 35 36
template<typename ele_g>
struct getAttrName<ele_g,false>
{
	/*! \brief Get attribute name
incardon's avatar
incardon committed
37
	 *
Pietro Incardona's avatar
Pietro Incardona committed
38 39
	 * \param i id of the attribute
	 * \param oprp post-fix to add
incardon's avatar
incardon committed
40 41
	 *
	 */
Pietro Incardona's avatar
Pietro Incardona committed
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
	static inline std::string get(size_t i, const std::string & oprp)
	{
		return std::string("attr" + std::to_string(i) + oprp);
	}
};

/*! \brief Get the vtk properties header appending a prefix at the end
 *
 * \tparam has_attributes indicate if the properties have attributes name
 * \param oprp prefix
 *
 */
template<unsigned int i, typename ele_g, bool has_attributes> std::string get_point_property_header_impl(const std::string & oprp)
{
	//! vertex node output string
	std::string v_out;

	typedef typename boost::mpl::at<typename ele_g::value_type::value_type::type,boost::mpl::int_<i>>::type ctype;

	// Check if T is a supported format
	// for now we support only scalar of native type
	if (std::rank<ctype>::value == 1)
incardon's avatar
incardon committed
64
	{
65
		if (std::extent<ctype>::value <= 3)
incardon's avatar
incardon committed
66
		{
67 68 69 70 71 72 73 74 75
			//Get type of the property
			std::string type = getType<typename std::remove_all_extents<ctype>::type>();

			// if the type is not supported skip-it
			if (type.size() == 0)
			{
				std::cerr << "Error " << __FILE__ << ":" << __LINE__ << " the type " << demangle(typeid(ctype).name()) << " is not supported by vtk\n";
				return "";
			}
incardon's avatar
incardon committed
76

77 78 79
			// Create point data properties
			v_out += "VECTORS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n";
		}
Pietro Incardona's avatar
Pietro Incardona committed
80 81 82 83 84 85 86 87 88 89 90
	}
	else
	{
		std::string type = getType<typename std::remove_all_extents<ctype>::type>();

		// if the type is not supported return
		if (type.size() == 0)
		{
			// We check if is a custom vtk writable object

			if (is_vtk_writable<ctype>::value == true)
incardon's avatar
incardon committed
91
			{
Pietro Incardona's avatar
Pietro Incardona committed
92
				type = getType<typename vtk_type<ctype,is_custom_vtk_writable<ctype>::value>::type >();
incardon's avatar
incardon committed
93

Pietro Incardona's avatar
Pietro Incardona committed
94 95 96 97 98
				// 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";
				else
					v_out += "VECTORS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n";
incardon's avatar
incardon committed
99
			}
Pietro Incardona's avatar
Pietro Incardona committed
100 101

			return v_out;
incardon's avatar
incardon committed
102 103
		}

Pietro Incardona's avatar
Pietro Incardona committed
104 105 106 107 108 109
		// Create point data properties
		v_out += "SCALARS " + getAttrName<ele_g,has_attributes>::get(i,oprp) + " " + type + "\n";

		// Default lookup table
		v_out += "LOOKUP_TABLE default\n";

incardon's avatar
incardon committed
110 111
	}

Pietro Incardona's avatar
Pietro Incardona committed
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
	// return the vertex list
	return v_out;
}

#if 0

/*! \brief This class specialize functions in the case the type T
 * has or not defined attributes
 *
 * In C++ partial specialization of a function is not allowed so we have to
 * encapsulate this function in a class
 *
 * \tparam has_attributes parameter that specialize the function in case the grid
 *         define or not attributes name
 *
 * \tparam Grid type we are processing
 * \tparam i the property we are going to write
 *
 */
template<bool has_attributes, typename St, typename ele_g, unsigned int i>
class prop_output_g
{
public:

	/*! \brief Return the VTK point data header for a typename T
incardon's avatar
incardon committed
137 138 139 140 141 142 143
	 *
	 * \tparam T type to write
	 * \param n_node number of the node
	 *
	 */
	static std::string get_point_property_header(const std::string & oprp)
	{
Pietro Incardona's avatar
Pietro Incardona committed
144 145 146
		return get_point_property_header_impl<i,ele_g,has_attributes>(oprp);
	}
};
incardon's avatar
incardon committed
147

Pietro Incardona's avatar
Pietro Incardona committed
148
#endif
149

Pietro Incardona's avatar
Pietro Incardona committed
150 151 152 153 154 155 156 157 158
/*! \brief Write the vectror property
 *
 * \tparam dim Dimensionality of the property
 *
 */
template<unsigned int dim, typename T>
class prop_write_out
{
public:
incardon's avatar
incardon committed
159

Pietro Incardona's avatar
Pietro Incardona committed
160 161
	template<typename vector, typename iterator, typename I> static void write(std::string & v_out, vector & vg, size_t k, iterator & it)
	{
incardon's avatar
incardon committed
162

Pietro Incardona's avatar
Pietro Incardona committed
163 164 165 166
		// Print the properties
		for (size_t i1 = 0 ; i1 < vtk_dims<T>::value ; i1++)
		{
			v_out += std::to_string(vg.get(k).g.get_o(it.get()).template get<I::value>().get_vtk(i1)) + " ";
167
		}
Pietro Incardona's avatar
Pietro Incardona committed
168
		if (vtk_dims<T>::value == 2)
169
		{
Pietro Incardona's avatar
Pietro Incardona committed
170
			v_out += "0.0";
171
		}
Pietro Incardona's avatar
Pietro Incardona committed
172
		v_out += "\n";
incardon's avatar
incardon committed
173
	}
Pietro Incardona's avatar
Pietro Incardona committed
174
};
incardon's avatar
incardon committed
175

Pietro Incardona's avatar
Pietro Incardona committed
176 177 178 179 180 181 182 183
/*! \brief Write the scalar property
 *
 *
 */
template<typename T>
class prop_write_out<1,T>
{
public:
incardon's avatar
incardon committed
184

Pietro Incardona's avatar
Pietro Incardona committed
185
	template<typename vector, typename iterator, typename I> static void write(std::string & v_out, vector & vg, size_t k, iterator & it)
incardon's avatar
incardon committed
186
	{
Pietro Incardona's avatar
Pietro Incardona committed
187 188
		// Print the property
		v_out += std::to_string(vg.get(k).g.get_o(it.get()).template get<I::value>()) + "\n";
incardon's avatar
incardon committed
189 190 191
	}
};

Pietro Incardona's avatar
Pietro Incardona committed
192
#if 0
incardon's avatar
incardon committed
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218

/*! \brief This class specialize functions in the case the type T
 * has not defined attributes
 *
 * In C++ partial specialization of a function is not allowed so we have to
 * encapsulate this function in a class
 *
 * \tparam has_attributes parameter that specialize the function in case the vertex
 *         define or not attributes name
 *
 * \tparam i id of the property we are going to write
 *
 */

template<typename ele_g, typename St, unsigned int i>
class prop_output_g<false,St,ele_g,i>
{
public:

	/*! \brief Get the vtk properties header appending a prefix at the end
	 *
	 * \param oprp prefix
	 *
	 */
	static std::string get_point_property_header(const std::string & oprp)
	{
Pietro Incardona's avatar
Pietro Incardona committed
219
		return get_point_property_header_impl<i,ele_g,false>(oprp);
incardon's avatar
incardon committed
220 221 222
	}
};

Pietro Incardona's avatar
Pietro Incardona committed
223 224
#endif

incardon's avatar
incardon committed
225 226
/*! \brief This class is an helper to create properties output from scalar and compile-time array elements
 *
227 228 229 230
 * \tparam I It is an boost::mpl::int_ that indicate which property we are writing
 * \tparam ele_g element type that store the grid information
 * \tparam St type of space where the grid live
 * \tparam T the type of the property
Pietro Incardona's avatar
Pietro Incardona committed
231
 * \tparam is_writable flag that indicate if a property is writable
incardon's avatar
incardon committed
232 233
 *
 */
Pietro Incardona's avatar
Pietro Incardona committed
234
template<typename I, typename ele_g, typename St, typename T, bool is_writable>
incardon's avatar
incardon committed
235 236 237 238 239 240 241 242
struct meta_prop
{
	inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out)
	{
    	// actual string size
    	size_t sz = v_out.size();

		// Produce the point properties header
Pietro Incardona's avatar
Pietro Incardona committed
243
    	v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>("");
incardon's avatar
incardon committed
244 245 246 247 248 249 250 251 252 253 254 255 256 257

		// If the output has changed, we have to write the properties
		if (v_out.size() != sz)
		{
			// Produce point data

			for (size_t k = 0 ; k < vg.size() ; k++)
			{
				//! Get a vertex iterator
				auto it = vg.get(k).g.getIterator();

				// if there is the next element
				while (it.isNext())
				{
Pietro Incardona's avatar
Pietro Incardona committed
258
					prop_write_out<vtk_dims<T>::value,T>::template write<decltype(vg),decltype(it),I>(v_out,vg,k,it);
incardon's avatar
incardon committed
259 260 261 262 263 264 265 266 267 268

					// increment the iterator and counter
					++it;
				}
			}
		}
	}
};

//! Partial specialization for N=1 1D-Array
Pietro Incardona's avatar
Pietro Incardona committed
269 270
template<typename I, typename ele_g, typename St, typename T, size_t N1, bool is_writable>
struct meta_prop<I, ele_g,St,T[N1],is_writable>
incardon's avatar
incardon committed
271 272 273
{
	inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out)
	{
274 275
	    // actual string size
	    size_t sz = v_out.size();
incardon's avatar
incardon committed
276

277
		// Produce the point properties header
Pietro Incardona's avatar
Pietro Incardona committed
278
		v_out += get_point_property_header_impl<I::value,ele_g,has_attributes<typename ele_g::value_type::value_type>::value>("");
incardon's avatar
incardon committed
279

280 281 282 283 284 285
		// If the output has changed, we have to write the properties
		if (v_out.size() != sz)
		{
			// Produce point data

			for (size_t k = 0 ; k < vg.size() ; k++)
incardon's avatar
incardon committed
286
			{
287 288
				//! Get a vertex iterator
				auto it = vg.get(k).g.getIterator();
incardon's avatar
incardon committed
289

290 291
				// if there is the next element
				while (it.isNext())
incardon's avatar
incardon committed
292
				{
293 294
					// Print the properties
					for (size_t i1 = 0 ; i1 < N1 ; i1++)
incardon's avatar
incardon committed
295
					{
296
						v_out += std::to_string(vg.get(k).g.get_o(it.get()).template get<I::value>()[i1]) + " ";
incardon's avatar
incardon committed
297
					}
298 299 300 301 302 303 304 305
					if (N1 == 2)
					{
						v_out += "0.0";
					}
					v_out += "\n";

					// increment the iterator and counter
					++it;
incardon's avatar
incardon committed
306 307 308 309 310 311 312
				}
			}
		}
	}
};

//! Partial specialization for N=2 2D-Array
Pietro Incardona's avatar
Pietro Incardona committed
313 314
template<typename I, typename ele_g, typename St ,typename T,size_t N1,size_t N2, bool is_writable>
struct meta_prop<I, ele_g,St, T[N1][N2],is_writable>
incardon's avatar
incardon committed
315 316 317 318 319 320 321 322 323 324 325
{
	inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out)
	{
		for (size_t i1 = 0 ; i1 < N1 ; i1++)
		{
			for (size_t i2 = 0 ; i2 < N2 ; i2++)
			{
		    	// actual string size
		    	size_t sz = v_out.size();

				// Produce the point properties header
Pietro Incardona's avatar
Pietro Incardona committed
326
				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));
incardon's avatar
incardon committed
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353

				// If the output has changed, we have to write the properties
				if (v_out.size() != sz)
				{
					// Produce point data

					for (size_t k = 0 ; k < vg.size() ; k++)
					{
						//! Get a vertex iterator
						auto it = vg.get(k).g.getIterator();

						// if there is the next element
						while (it.isNext())
						{
							// Print the property
							v_out += std::to_string(vg.get(k).g.get_o(it.get()).template get<I::value>()[i1][i2]) + "\n";

							// increment the iterator and counter
							++it;
						}
					}
				}
			}
		}
	}
};

Pietro Incardona's avatar
Pietro Incardona committed
354 355 356 357

//! Specialication when is not writable
template<typename I, typename ele_g, typename St, typename T>
struct meta_prop<I,ele_g,St,T,false>
incardon's avatar
incardon committed
358 359 360 361 362 363 364
{
	inline meta_prop(const openfpm::vector< ele_g > & vg, std::string & v_out)
	{
	}
};

#endif /* SRC_VTKWRITER_GRIDS_UTIL_HPP_ */