ug4
file_io_vtu_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2015: G-CSC, Goethe University Frankfurt
3  * Author: Sebastian Reiter
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef __H__UG_file_io_vtu_impl
34 #define __H__UG_file_io_vtu_impl
35 
36 #include <sstream>
37 #include <cstring>
40 
41 namespace ug{
42 
43 
44 template <class TAPosition>
45 bool LoadGridFromVTU(Grid& grid, ISubsetHandler& sh, const char* filename,
46  TAPosition& aPos)
47 {
48  GridReaderVTU vtuReader;
49  if(!vtuReader.parse_file(filename)){
50  UG_LOG("ERROR in LoadGridFromVTU: File not found: " << filename << std::endl);
51  return false;
52  }
53 
54  if(vtuReader.num_grids() < 1){
55  UG_LOG("ERROR in LoadGridFromVTU: File contains no grid.\n");
56  return false;
57  }
58 
59  vtuReader.grid(grid, 0, aPos);
60 
61  vtuReader.subset_handler(sh, 0, 0);
62 
63  return true;
64 }
65 
66 template <class TAPosition>
67 bool SaveGridToVTU(Grid& grid, ISubsetHandler* psh, const char* filename,
68  TAPosition& aPos)
69 {
70  GridWriterVTU vtuWriter;
71  std::ofstream out(filename);
72 
73  vtuWriter.set_stream(&out);
74 
75  vtuWriter.new_piece(grid, psh, aPos);
76 
77  vtuWriter.finish();
78 
79  return true;
80 }
81 
82 
85 // GridWriterVTU
87 
88 std::ostream& GridWriterVTU::
89 out_stream()
90 {
91  UG_COND_THROW(!m_pout, "Invalid ostream specified fo GridWriterVTU!");
92  return *m_pout;
93 }
94 
95 template <class TPositionAttachment>
97 new_piece(Grid& grid, ISubsetHandler* psh, TPositionAttachment& aPos)
98 {
99  using namespace std;
100 
101  if(m_pieceMode == OPEN)
102  end_piece();
103 
104  m_pieceMode = OPEN;
107 
108  ostream& out = out_stream();
109 
110  m_curGrid = &grid;
111  m_curSH = psh;
112 
113  m_pieceSubsetHandlers.clear();
114  m_cells.clear();
115 
116 // if a subset-handler is specified, all grid elements which are assigned to
117 // subsets are considered as cells.
118 // If not, only elements of highest dimension are considered as cells.
119 
120  if(psh){
121  add_subset_handler(*psh, string("regions"));
122  collect_cells<Vertex>(m_cells, grid, IsNotInSubset(*psh, -1));
123  collect_cells<Edge>(m_cells, grid, IsNotInSubset(*psh, -1));
124  collect_cells<Face>(m_cells, grid, IsNotInSubset(*psh, -1));
125  collect_cells<Volume>(m_cells, grid, IsNotInSubset(*psh, -1));
126  }
127  else{
128  if(grid.num<Volume>() > 0)
129  collect_cells<Volume>(m_cells, grid, ConsiderAll());
130  else if(grid.num<Face>() > 0)
131  collect_cells<Face>(m_cells, grid, ConsiderAll());
132  else if(grid.num<Edge>() > 0)
133  collect_cells<Edge>(m_cells, grid, ConsiderAll());
134  else
135  collect_cells<Vertex>(m_cells, grid, ConsiderAll());
136  }
137 
138  out << " <Piece NumberOfPoints=\"" << grid.num<Vertex>() << "\""
139  << " NumberOfCells=\"" << m_cells.size() << "\">" << endl;
140 
141 
142 // write points
143  out << " <Points>" << endl;
144  write_vector_data<Vertex>(grid, aPos, "");
145  out << " </Points>" << endl;
146 
147 // write cells
148 // first we'll assign indices to the vertices, which can then be used as
149 // references by the cells.
150  AInt aInd;
151  grid.attach_to_vertices(aInd);
152  Grid::VertexAttachmentAccessor<AInt> aaInd(grid, aInd);
153  AssignIndices(grid.begin<Vertex>(), grid.end<Vertex>(), aaInd, 0);
154 
155  write_cells(m_cells, grid, aaInd);
156 
157  grid.detach_from_vertices(aInd);
158 
159  return true;
160 }
161 
162 
163 template <class TElem, class TAttachment>
165 write_vector_data(Grid& grid,
166  TAttachment aData,
167  const char* name,
168  typename Grid::traits<TElem>::callback consider_elem)
169 {
170  using namespace std;
171  ostream& out = out_stream();
172 
173  typedef typename TAttachment::ValueType vector_t;
174  typedef typename Grid::traits<TElem>::iterator iter_t;
175 
177 
178  write_data_array_header("Float32", "", vector_t::Size);
179  out << " ";
180 
181  for(iter_t i = grid.begin<TElem>(); i != grid.end<TElem>(); ++i){
182  vector_t& v = aaData[*i];
183  for(size_t c = 0; c < vector_t::Size; ++c){
184  out << " " << v[c];
185  }
186  }
187  out << endl;
189 }
190 
191 template <class TElem>
193 collect_cells(std::vector<GridObject*>& cellsOut, Grid& grid,
194  typename Grid::traits<TElem>::callback consider_elem)
195 {
196  typedef typename Grid::traits<TElem>::iterator iter_t;
197  for(iter_t i = grid.begin<TElem>(); i != grid.end<TElem>(); ++i){
198  if(consider_elem(*i))
199  cellsOut.push_back(*i);
200  }
201 }
202 
203 
204 
205 
208 // GridReaderVTU
210 template <class TPositionAttachment>
212 grid(Grid& gridOut, size_t index, TPositionAttachment& aPos)
213 {
214  using namespace rapidxml;
215  using namespace std;
216 
217 // make sure that a node at the given index exists
218  if(num_grids() <= index){
219  UG_LOG(" GridReaderVTU::read: bad grid index!\n");
220  return false;
221  }
222 
223  Grid& grid = gridOut;
224 
225 // Since we have to create all elements in the correct order and
226 // since we have to make sure that no elements are created in between,
227 // we'll first disable all grid-options and reenable them later on
228  uint gridopts = grid.get_options();
230 
231 // access node data
232  if(!grid.has_vertex_attachment(aPos)){
233  grid.attach_to_vertices(aPos);
234  }
235 
237 
238 // store the grid in the grid-vector and assign indices to the vertices
239  m_entries[index].grid = &grid;
240 
241 // get the grid-node and the vertex-vector
242  xml_node<>* gridNode = m_entries[index].node;
243  vector<Vertex*>& vertices = m_entries[index].vertices;
244  vector<GridObject*>& cells = m_entries[index].cells;
245 
246 // iterate over all pieces
247  xml_node<>* pieceNode = gridNode;
248 // first we'll create all points and cells, then we'll parse point- and cell-data
249  xml_node<>* pointsNode = pieceNode->first_node("Points");
250  UG_COND_THROW(pointsNode == NULL, "Missing Points node in UnstructuredGrid node!")
251 
252  size_t vrtOffset = vertices.size();
253  create_vertices(vertices, grid, pointsNode, aaPos);
254 
255  xml_node<>* cellsNode = pieceNode->first_node("Cells");
256  UG_COND_THROW(cellsNode == NULL, "Missing Cells node in UnstructuredGrid node!")
257  create_cells(cells, grid, cellsNode, vertices, vrtOffset);
258 
259 // reenable the grids options.
260  grid.set_options(gridopts);
261 
262  return true;
263 }
264 
265 template <class TAAPos>
267 create_vertices(std::vector<Vertex*>& vrtsOut, Grid& grid,
268  rapidxml::xml_node<>* vrtNode, TAAPos aaPos)
269 {
270  using namespace rapidxml;
271  using namespace std;
272 
273  xml_node<>* dataNode = vrtNode->first_node("DataArray");
274  UG_COND_THROW(!dataNode, "Missing DataArray node in Points node");
275 
276  int numSrcCoords = -1;
277  xml_attribute<>* attrib = dataNode->first_attribute("NumberOfComponents");
278  if(attrib)
279  numSrcCoords = atoi(attrib->value());
280 
281  int numDestCoords = (int)TAAPos::ValueType::Size;
282 
283  assert(numDestCoords > 0 && "bad position attachment type");
284 
285  if(numSrcCoords < 1 || numDestCoords < 1)
286  return false;
287 
288 // create a buffer with which we can access the data
289  string str(dataNode->value(), dataNode->value_size());
290  stringstream ss(str, ios_base::in);
291 
292 // if numDestCoords == numSrcCoords parsing will be faster
293  if(numSrcCoords == numDestCoords){
294  while(!ss.eof()){
295  // read the data
296  typename TAAPos::ValueType v;
297 
298  for(int i = 0; i < numSrcCoords; ++i)
299  ss >> v[i];
300 
301  // make sure that everything went right
302  if(ss.fail())
303  break;
304 
305  // create a new vertex
306  RegularVertex* vrt = *grid.create<RegularVertex>();
307  vrtsOut.push_back(vrt);
308 
309  // set the coordinates
310  aaPos[vrt] = v;
311  }
312  }
313  else{
314  // we have to be careful with reading.
315  // if numDestCoords < numSrcCoords we'll ignore some coords,
316  // in the other case we'll add some 0's.
317  int minNumCoords = min(numSrcCoords, numDestCoords);
318  typename TAAPos::ValueType::value_type dummy = 0;
319 
320  while(!ss.eof()){
321  // read the data
322  typename TAAPos::ValueType v;
323 
324  int iMin;
325  for(iMin = 0; iMin < minNumCoords; ++iMin)
326  ss >> v[iMin];
327 
328  // ignore unused entries in the input buffer
329  for(int i = iMin; i < numSrcCoords; ++i)
330  ss >> dummy;
331 
332  // add 0's to the vector
333  for(int i = iMin; i < numDestCoords; ++i)
334  v[i] = 0;
335 
336  // make sure that everything went right
337  if(ss.fail()){
338  UG_LOG("GridReaderVTU::create_vertices: Failed to read vertex.\n");
339  return false;
340  }
341 
342  // create a new vertex
343  RegularVertex* vrt = *grid.create<RegularVertex>();
344  vrtsOut.push_back(vrt);
345 
346  // set the coordinates
347  aaPos[vrt] = v;
348  }
349  }
350 
351  return true;
352 }
353 
354 
355 template <class T>
357 read_scalar_data(std::vector<T>& dataOut,
358  rapidxml::xml_node<>* dataNode,
359  bool clearData)
360 {
361  using namespace std;
362 
363  if(clearData)
364  dataOut.clear();
365 
366 // create a buffer with which we can access the data
367  string str(dataNode->value(), dataNode->value_size());
368  stringstream ss(str, ios_base::in);
369 
370  while(!ss.eof()){
371  // read the data
372  T d;
373  ss >> d;
374 
375  // make sure that everything went right
376  if(ss.fail())
377  break;
378 
379  dataOut.push_back(d);
380  }
381 }
382 
383 template <class T>
385 check_indices(std::vector<T>& inds, size_t first, size_t num, size_t validSize)
386 {
387  UG_COND_THROW(first + num > inds.size(),
388  "Bad index range encountered during parsing of " << m_filename);
389 
390  for(size_t i = first; i < num; ++i){
391  UG_COND_THROW(inds[i] >= validSize,
392  "Bad index encountered during parsing of " << m_filename);
393  }
394 }
395 
396 }// end of namespace
397 
398 #endif //__H__file_io_vtu_impl
location name
Definition: checkpoint_util.lua:128
callback that always returns true
Definition: basic_callbacks.h:50
Base-class for edges.
Definition: grid_base_objects.h:397
Faces are 2-dimensional objects.
Definition: grid_base_objects.h:510
the generic attachment-accessor for access to grids attachment pipes.
Definition: grid.h:182
Manages the elements of a grid and their interconnection.
Definition: grid.h:132
size_t num() const
Definition: grid_impl.hpp:230
void detach_from_vertices(IAttachment &attachment)
Definition: grid.h:787
geometry_traits< TGeomObj >::iterator begin()
Definition: grid_impl.hpp:164
bool has_vertex_attachment(IAttachment &attachment)
Definition: grid.h:798
void set_options(uint options)
Definition: grid.cpp:701
void attach_to_vertices(IAttachment &attachment, bool passOnValues)
Definition: grid.h:728
geometry_traits< TGeomObj >::iterator create(GridObject *pParent=NULL)
create a custom element.
Definition: grid_impl.hpp:69
geometry_traits< TGeomObj >::iterator end()
Definition: grid_impl.hpp:175
uint get_options() const
Definition: grid.cpp:706
Grants read access to vtu (vtk) files.
Definition: file_io_vtu.h:191
size_t num_grids() const
returns the number of grids in the given file
Definition: file_io_vtu.h:200
bool parse_file(const char *filename)
parses an xml file
Definition: file_io_vtu.cpp:451
bool subset_handler(ISubsetHandler &shOut, size_t refGridIndex, size_t subsetHandlerIndex)
fills the given subset-handler
Definition: file_io_vtu.cpp:592
bool create_vertices(std::vector< Vertex * > &vrtsOut, Grid &grid, rapidxml::xml_node<> *vrtNode, TAAPos aaPos)
creates vertices from a vertex-node.
Definition: file_io_vtu_impl.h:267
void read_scalar_data(std::vector< T > &dataOut, rapidxml::xml_node<> *dataNode, bool clearData=true)
Definition: file_io_vtu_impl.h:357
bool grid(Grid &gridOut, size_t index, TPositionAttachment &aPos)
returns the i-th grid.
Definition: file_io_vtu_impl.h:212
void check_indices(std::vector< T > &inds, size_t first, size_t num, size_t max)
Definition: file_io_vtu_impl.h:385
Grants write access to vtu files.
Definition: file_io_vtu.h:87
Mode m_pointDataMode
Definition: file_io_vtu.h:171
void write_data_array_footer()
Definition: file_io_vtu.cpp:195
Mode m_pieceMode
Definition: file_io_vtu.h:170
std::ostream * m_pout
Definition: file_io_vtu.h:169
std::vector< std::pair< ISubsetHandler *, std::string > > m_pieceSubsetHandlers
Definition: file_io_vtu.h:178
void set_stream(std::ostream *out)
Pass a pointer to an ostream to which the data shall be written.
Definition: file_io_vtu.cpp:153
void write_data_array_header(const char *type, const char *name, int numberOfComponents)
Definition: file_io_vtu.cpp:181
@ NONE
Definition: file_io_vtu.h:164
@ OPEN
Definition: file_io_vtu.h:165
Mode m_cellDataMode
Definition: file_io_vtu.h:172
bool new_piece(Grid &grid, ISubsetHandler *psh, TPositionAttachment &aPos)
Definition: file_io_vtu_impl.h:97
void write_vector_data(Grid &grid, TAttachment aData, const char *name="", typename Grid::traits< TElem >::callback consider_elem=ConsiderAll())
Definition: file_io_vtu_impl.h:165
Grid * m_curGrid
Definition: file_io_vtu.h:174
void finish()
Definition: file_io_vtu.cpp:380
std::vector< GridObject * > m_cells
Definition: file_io_vtu.h:177
std::ostream & out_stream()
Definition: file_io_vtu_impl.h:89
void end_piece()
Definition: file_io_vtu.cpp:358
void write_cells(std::vector< GridObject * > &cells, Grid &grid, AAVrtIndex aaInd)
Definition: file_io_vtu.cpp:286
ISubsetHandler * m_curSH
Definition: file_io_vtu.h:175
void add_subset_handler(ISubsetHandler &sh, const std::string &name)
You may add subset-handlers which will be written as regions to the vtk-file.
Definition: file_io_vtu.cpp:172
void collect_cells(std::vector< GridObject * > &cellsOut, Grid &grid, typename Grid::traits< TElem >::callback consider_elem=ConsiderAll())
Definition: file_io_vtu_impl.h:193
Definition: subset_handler_interface.h:223
Element callback that returns true, if an element is not contained in a subset.
Definition: subset_callbacks.h:68
A basic vertex-type.
Definition: grid_objects_0d.h:62
Base-class for all vertex-types.
Definition: grid_base_objects.h:231
Volumes are 3-dimensional objects.
Definition: grid_base_objects.h:754
void AssignIndices(TIterator begin, TIterator end, TAAInt &aaInt, int baseIndex=0)
assigns indices to the elements between begin and end.
Definition: attachment_util_impl.hpp:178
@ GRIDOPT_NONE
Definition: grid_constants.h:91
#define UG_LOG(msg)
Definition: log.h:367
unsigned int uint
Definition: types.h:114
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition: error.h:61
std::pair< counting_iterator< size_t >, counting_iterator< size_t > > vertices(ug::BidirectionalMatrix< T > const &M)
Definition: bidirectional_boost.h:60
Definition: smart_pointer.h:814
the ug namespace
bool SaveGridToVTU(Grid &grid, ISubsetHandler *psh, const char *filename, TAPosition &aPos)
Writes a grid to a vtu (vtk unstructured mesh) file.
Definition: file_io_vtu_impl.h:67
bool LoadGridFromVTU(Grid &grid, ISubsetHandler &sh, const char *filename)
Reads a grid to a vtu (vtk unstructured mesh) file.
Definition: file_io_vtu.cpp:103
T value_type
Definition: sparsematrix_interface.h:2
boost::function< bool(base_object *)> callback
callback type for the elements base type.
Definition: grid.h:150
geometry_traits< TElem >::iterator iterator
Definition: grid.h:143