Line data Source code
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__LIB_GRID__FILE_IO_VTU__
34 : #define __H__LIB_GRID__FILE_IO_VTU__
35 :
36 : #include <iostream>
37 : #include <vector>
38 : #include <utility>
39 : #include "common/parser/rapidxml/rapidxml.hpp"
40 : #include "lib_grid/grid/grid.h"
41 : #include "lib_grid/multi_grid.h"
42 : #include "lib_grid/tools/subset_handler_interface.h"
43 : #include "lib_grid/tools/selector_interface.h"
44 : #include "lib_grid/common_attachments.h"
45 : #include "lib_grid/grid_objects/grid_objects.h"
46 : #include "lib_grid/callbacks/basic_callbacks.h"
47 :
48 : namespace ug
49 : {
50 :
51 : ////////////////////////////////////////////////////////////////////////
52 : /// Reads a grid to an vtu (vtk) file. internally uses GridReaderVTK.
53 : /** The position attachment can be specified. Since the type of the
54 : * position attachment is a template parameter, MathVector attachments
55 : * of any dimension are supported. Especially ug::aPosition, ug::aPostion2
56 : * and ug::aPosition1.
57 : */
58 : template <class TAPosition>
59 : bool LoadGridFromVTU(Grid& grid, ISubsetHandler& sh,
60 : const char* filename, APosition& aPos);
61 :
62 : /// Reads a grid to a vtu (vtk unstructured mesh) file.
63 : /** Before reading a grid from file, this method searches for the
64 : * attached standard position attachment with the highest dimension.
65 : * This will be used as position-attachment in a call to the overloaded
66 : * version of LoadGridFromVTU.
67 : *
68 : * If no standard attachment is found, aPosition will be attached and used.
69 : */
70 : bool LoadGridFromVTU(Grid& grid, ISubsetHandler& sh,
71 : const char* filename);
72 :
73 :
74 : /// Writes a grid to a vtu (vtk unstructured mesh) file
75 : template <class TAPosition>
76 : bool SaveGridToVTU(Grid& grid, ISubsetHandler* psh, const char* filename,
77 : TAPosition& aPos);
78 :
79 :
80 : ////////////////////////////////////////////////////////////////////////
81 : ////////////////////////////////////////////////////////////////////////
82 : /// Grants write access to vtu files.
83 : /** Make sure that all elements added via one of the add_* methods
84 : * exist until the FileAccessor is destroyed.
85 : */
86 : class GridWriterVTU
87 : {
88 : public:
89 : GridWriterVTU();
90 : /// Pass a pointer to an ostream to which the data shall be written.
91 : /** Make sure, that the stream is open and stays valid while write operations
92 : * are performed.*/
93 : GridWriterVTU(std::ostream* out);
94 :
95 : virtual ~GridWriterVTU();
96 :
97 : /// Pass a pointer to an ostream to which the data shall be written.
98 : /** Make sure, that the stream is open and stays valid while write operations
99 : * are performed.*/
100 : void set_stream(std::ostream* out);
101 :
102 : void finish();
103 :
104 : /** TPositionAttachments value type has to be compatible with MathVector.
105 : * Make sure that aPos is attached to the vertices of the grid.
106 : * If a SubsetHandler is specified through 'psh' (NULL is valid too), it will
107 : * automatically be passed to 'add_subset_handler' with the name "regions".
108 : * If you pass a subset handler to this method, furthermore only those elements
109 : * which are assigned to subsets will be written to the file as cells.
110 : * If you don't pass a subset-handler, only elements of highest dimension are
111 : * written to the file.*/
112 : template <class TPositionAttachment>
113 : bool new_piece(Grid& grid, ISubsetHandler* psh,
114 : TPositionAttachment& aPos);
115 :
116 : /// You may add subset-handlers which will be written as regions to the vtk-file.
117 : /** Make sure to add subset-handlers before 'end_cell_data' is called.
118 : * Note that if you pass a subset-handler to 'new_piece', then it will be
119 : * automatically registered with the name "regions".*/
120 : void add_subset_handler(ISubsetHandler& sh, const std::string& name);
121 :
122 : void begin_point_data();
123 : //...
124 : void end_point_data();
125 :
126 : void begin_cell_data();
127 : void end_cell_data();
128 :
129 : protected:
130 : typedef Grid::VertexAttachmentAccessor<AInt> AAVrtIndex;
131 : typedef Grid::EdgeAttachmentAccessor<AInt> AAEdgeIndex;
132 : typedef Grid::FaceAttachmentAccessor<AInt> AAFaceIndex;
133 : typedef Grid::VolumeAttachmentAccessor<AInt> AAVolIndex;
134 :
135 : inline std::ostream& out_stream();
136 :
137 : /** \param name: Set to "" to omit this parameter in the output.
138 : * \param numberOfComponents: Set to 0 to omit this parameter in the output.*/
139 : void write_data_array_header(const char* type, const char* name,
140 : int numberOfComponents);
141 :
142 : void write_data_array_footer();
143 :
144 : template <class TElem, class TAttachment>
145 : void write_vector_data(Grid& grid,
146 : TAttachment aData,
147 : const char* name = "",
148 : typename Grid::traits<TElem>::callback consider_elem =
149 : ConsiderAll());
150 :
151 : template <class TElem>
152 : void collect_cells(std::vector<GridObject*>& cellsOut,
153 : Grid& grid,
154 : typename Grid::traits<TElem>::callback consider_elem =
155 : ConsiderAll());
156 :
157 : void write_cells(std::vector<GridObject*>& cells, Grid& grid,
158 : AAVrtIndex aaInd);
159 :
160 : void end_piece();
161 :
162 :
163 : enum Mode{
164 : NONE,
165 : OPEN,
166 : CLOSED
167 : };
168 :
169 : std::ostream* m_pout;
170 : Mode m_pieceMode;
171 : Mode m_pointDataMode;
172 : Mode m_cellDataMode;
173 :
174 : Grid* m_curGrid;
175 : ISubsetHandler* m_curSH;
176 :
177 : std::vector<GridObject*> m_cells;
178 : std::vector<std::pair<ISubsetHandler*, std::string> > m_pieceSubsetHandlers;
179 : };
180 :
181 :
182 :
183 : ////////////////////////////////////////////////////////////////////////
184 : /// Grants read access to vtu (vtk) files.
185 : /** Before any data can be retrieved using the get_* methods, a file
186 : * has to be successfully loaded using load_file.
187 : *
188 : * \todo: Improve performance by using in-situ stringstreams during element creation.
189 : */
190 : class GridReaderVTU
191 : {
192 : public:
193 : GridReaderVTU();
194 : virtual ~GridReaderVTU();
195 :
196 : /// parses an xml file
197 : bool parse_file(const char* filename);
198 :
199 : /// returns the number of grids in the given file
200 : size_t num_grids() const {return m_entries.size();}
201 :
202 : /// returns the i-th grid.
203 : /** TPositionAttachments value type has to be compatible with MathVector.
204 : * Make sure that a file has already been loaded.*/
205 : template <class TPositionAttachment>
206 : bool grid(Grid& gridOut, size_t index, TPositionAttachment& aPos);
207 :
208 : /// returns the name of the i-th grid
209 : const char* get_grid_name(size_t index) const;
210 :
211 : /// returns the number of subset handlers for the given grid
212 : size_t num_subset_handlers(size_t refGridIndex) const;
213 :
214 : /// returns the name of the given subset handler
215 : const char* get_subset_handler_name(size_t refGridIndex,
216 : size_t subsetHandlerIndex) const;
217 :
218 : /// fills the given subset-handler
219 : bool subset_handler(ISubsetHandler& shOut,
220 : size_t refGridIndex,
221 : size_t subsetHandlerIndex);
222 :
223 : static std::string const getRegionOfInterestIdentifyer()
224 : { return m_regionOfInterest; }
225 :
226 : static void setRegionOfInterestIdentifier( std::string const & regOfInt )
227 : { m_regionOfInterest = regOfInt; }
228 :
229 : protected:
230 : struct SubsetHandlerEntry
231 : {
232 0 : SubsetHandlerEntry(rapidxml::xml_node<>* n) : node(n), sh(NULL) {}
233 :
234 : rapidxml::xml_node<>* node;
235 : ISubsetHandler* sh;
236 : };
237 :
238 0 : struct GridEntry
239 : {
240 0 : GridEntry(rapidxml::xml_node<>* n) : node(n), grid(NULL), mg(NULL) {}
241 :
242 : rapidxml::xml_node<>* node;
243 : Grid* grid;
244 : MultiGrid* mg;
245 : std::vector<SubsetHandlerEntry> subsetHandlerEntries;
246 : std::vector<Vertex*> vertices;
247 : std::vector<GridObject*> cells;
248 : };
249 :
250 : protected:
251 : /// initializes internal arrays
252 : /** searches for all grid-nodes and stores, resizes m_entries and stores
253 : * the node for each entry.
254 : *
255 : * If you create your own version of this method, don't forget to call the
256 : * base-class implementation!*/
257 : virtual bool new_document_parsed();
258 :
259 : /// creates vertices from a vertex-node.
260 : /** if aaPos has more coordinates per vertex than the vrtNode,
261 : * 0's will be appended. If it has less, unused coordinates will
262 : * be ignored.*/
263 : template <class TAAPos>
264 : bool create_vertices(std::vector<Vertex*>& vrtsOut, Grid& grid,
265 : rapidxml::xml_node<>* vrtNode, TAAPos aaPos);
266 :
267 : bool create_cells(std::vector<GridObject*>& cellsOut,
268 : Grid& grid,
269 : rapidxml::xml_node<>* node,
270 : std::vector<Vertex*> vertices,
271 : size_t pieceVrtOffset);
272 :
273 : template <class T>
274 : void read_scalar_data(std::vector<T>& dataOut,
275 : rapidxml::xml_node<>* dataNode,
276 : bool clearData = true);
277 :
278 : void trafoDblVec2Int( std::vector<double> const & dblVec, std::vector<int> & intVec );
279 :
280 : template <class T>
281 : void check_indices(std::vector<T>& inds, size_t first, size_t num, size_t max);
282 :
283 : rapidxml::xml_node<>* find_child_node_by_argument_value(
284 : rapidxml::xml_node<>* parent,
285 : const char* nodeName,
286 : const char* argName,
287 : const char* argValue);
288 : protected:
289 : /// stores the file-name
290 : std::string m_filename;
291 :
292 : /// the xml_document which stores the data
293 : rapidxml::xml_document<> m_doc;
294 :
295 : /// holds grids which already have been created
296 : std::vector<GridEntry> m_entries;
297 :
298 :
299 :
300 : static std::string m_regionOfInterest; // ProMesh standard = "regions", in Braunschweig case often "Material Id", but not always
301 :
302 : };
303 :
304 : }// end of namespace
305 :
306 : ////////////////////////////////
307 : // include implementation
308 : #include "file_io_vtu_impl.h"
309 :
310 : #endif
|