1 /**
2 * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3 * storing and accessing finite element mesh data.
4 *
5 * Copyright 2004 Sandia Corporation. Under the terms of Contract
6 * DE-AC04-94AL85000 with Sandia Coroporation, the U.S. Government
7 * retains certain rights in this software.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 */
15
16 //-------------------------------------------------------------------------
17 // Filename : ReadRTT.hpp
18 //
19 // Purpose : RTT file reader
20 //
21 // Creator : Andrew Davis
22 //
23 // Date : 02/2014
24 //
25 //-------------------------------------------------------------------------
26
27 /**
28 * The RTT file format is used by the Attila deterministic radiation
29 * transport code. The specific mesh format can be found in Chapter 9
30 * of the Attila manual. The format is defined by xml like, block/end block
31 * type syntax. The implementation at the time of writing supports a subset
32 * of the whole format, and even Attila does not support the entireity of
33 * its own mesh format.
34 *
35 * The mesh contains several features, that as a whole allow the conversion
36 * from the RTT format, to a DAGMC geometry and a Tet Mesh for tallying.
37 *
38 * Sides - Defines the 6 boundary condtions for top, bottom, front, back
39 * left and right, as well as internal and external.
40 *---------------------------------------------------------------------
41 * Faces - Logically equivalent to surfaces in DAGMC, containers for triangles, includes
42 * the definition of the sense of the faces with respect to the Cells (volumes)
43 * which bound it.
44 *
45 * The face syntax looks like
46 *
47 * 1 (+)Pyrex@14
48 *
49 * This means Face (surface) 1 is used to define the insde of the Pyrex cell only
50 *
51 * 75 (+)Pyrex/(-)Fuel30@25
52 *
53 * This means Face (surface) 75 is used by both Cell Pyrex and Cell Fuel 30,
54 * the + and - signs refer to the sense, i.e. the inside sense defines the Pyrex and
55 * the outside sense defines the Fuel.
56 *---------------------------------------------------------------------
57 * Cells - Entityset like coillections of tetrahedra which define contiguous material properties
58 *
59 * cell_flags
60 * 1 REGIONS
61 * 1 Pyrex
62 * end_cell_flags
63 *
64 * Defines that there is 1 region called Pyrex
65 *---------------------------------------------------------------------
66 * Nodes - Defines the vertices for facets and tets, the syntax of which is shown below
67 *
68 * 100 1.8900000000E+03 0.0000000000E+00 5.0000000000E+03 100
69 *
70 * Defines that this is node 100, and has the coordinates 1890.0, 0.0 5000.0 cm
71 **---------------------------------------------------------------------
72 * Side (element) - Triangles
73 *
74 * 1 3 874 132 154 3 6365
75 *
76 * Defines that this is side element 1, it has 3 nodes, 874, 132 and 154,
77 * side ID 3 and surface number 6365
78 *---------------------------------------------------------------------
79 * Cells (element) - Tetrahedra
80 *
81 * 691 4 599 556 1218 1216 2
82 *
83 * Defines that this is tet 691, it has 4 connections to nodes 599, 556,
84 * 1218, 1216 and belongs to cell number 2.
85 *
86 */
87
88 #ifndef READRTT_HPP
89 #define READRTT_HPP
90
91 #ifndef IS_BUILDING_MB
92 #error "ReadRTT.hpp isn't supposed to be included into an application"
93 #endif
94
95 #include <iostream>
96 #include <fstream>
97 #include <sstream>
98 #include <map>
99 #include <vector>
100
101 #include "moab/Interface.hpp"
102 #include "moab/ReaderIface.hpp"
103 #include "FileTokenizer.hpp"
104 #include "moab/RangeMap.hpp"
105
106 namespace moab
107 {
108
109 class ReadUtilIface;
110 class GeomTopoTool;
111
112 class ReadRTT : public ReaderIface
113 {
114
115 public:
116 // factory method
117 static ReaderIface* factory( Interface* );
118
119 // generic overloaded core -> load_file
120 ErrorCode load_file( const char* file_name,
121 const EntityHandle* file_set,
122 const FileOptions& opts,
123 const SubsetList* subset_list = 0,
124 const Tag* file_id_tag = 0 );
125 // constructor
126 ReadRTT( Interface* impl = NULL );
127
128 // destructor
129 virtual ~ReadRTT();
130
131 // implementation empty
132 ErrorCode read_tag_values( const char* file_name,
133 const char* tag_name,
134 const FileOptions& opts,
135 std::vector< int >& tag_values_out,
136 const SubsetList* subset_list = 0 );
137
138 protected:
139 // private functions
140 private:
141 // structure to hold the header data
142 struct headerData
143 {
144 std::string version;
145 std::string title;
146 std::string date;
147 };
148
149 // structure to hold sense & vol data
150 struct boundary
151 {
152 int sense;
153 std::string name;
154 };
155
156 // structure to hold side data
157 struct side
158 {
159 int id;
160 int senses[2];
161 std::string names[2];
162 side() : id( 0 )
163 {
164 senses[0] = senses[1] = 0;
165 names[0] = names[1] = "";
166 }
167 };
168
169 // structure to hold cell data
170 struct cell
171 {
172 int id;
173 std::string name;
174 cell() : id( 0 ), name( "" ) {}
175 };
176
177 // structure to hold node data
178 struct node
179 {
180 int id;
181 double x, y, z;
182 node() : id( 0 ), x( 0. ), y( 0. ), z( 0. ) {}
183 };
184
185 // structure to hold facet data
186 struct facet
187 {
188 int id;
189 int connectivity[3];
190 int side_id;
191 int surface_number;
192 facet() : id( 0 ), side_id( 0 ), surface_number( 0 )
193 {
194 for( int k = 0; k < 3; k++ )
195 connectivity[k] = 0;
196 }
197 };
198
199 // structure to hold tet data
200 struct tet
201 {
202 int id;
203 int connectivity[4];
204 int material_number;
205 // with c++11 we could use tet(): id(0), connectivity({0}), material_number(0) {}
206 tet() : id( 0 ), material_number( 0 )
207 {
208 for( int k = 0; k < 4; k++ )
209 connectivity[k] = 0;
210 }
211 };
212
213 /**
214 * generates the topology of the problem from the already read input data, loops over the 2 and
215 * 3 dimension macrodata that exist from the rtt file, sides = dagmc surfaces, cells = dagmc
216 * cells, creates a meshset for each surface and tags with the id number, and similarly makes a
217 * meshset for dagmc cells and tags with the id number. The surfaces are added to the s surface
218 * map, where the key is the surface ID number (1->N) and (cells and surfaces are added to an
219 * dimesional entity map stored in the class
220 *
221 * @param side_data, vector of side data
222 * @param cell_data, vector of vector of cell data
223 * @param surface_map, reference to the surface map of data
224 *
225 */
226 ErrorCode generate_topology( std::vector< side > side_data,
227 std::vector< cell > cell_data,
228 std::map< int, EntityHandle >& surface_map );
229 /**
230 * Generate parent child links to create DAGMC like structure of surface meshsets being children
231 * of parent cell meshsets. By looping over the surfaces (1->N), look in the description of the
232 * cells that are shared by that surface, and then make the surface the child of the parent
233 * volume. The appropriate sense data will be set later
234 *
235 * @param num_ents[4], array containing the number of surfaces, cells, groups etc
236 * @param entity_map[4], vector of maps containing data by dimension
237 * @param side_data, vector of all the side data in the problem
238 * @param cell_data, vector of the cell data in the problem
239 *
240 */
241 void generate_parent_child_links( int num_ents[4],
242 std::vector< EntityHandle > entity_map[4],
243 std::vector< side > side_data,
244 std::vector< cell > cell_data );
245 /**
246 * Sets the appropriate surface senses for each surface in the problem. By looping through all
247 * the surfaces, we determine from the side_data vector, the volume id's that are shared, then
248 * using 1 to mean +ve sense and -1 to mean -ve sense wrt the volume.
249 *
250 * @param num_ents[4], array containing the number of surfaces, cells, groups etc
251 * @param entity_map[4], vector of maps containing data by dimension
252 * @param side_data, vector of all the side data in the problem
253 * @param cell_data, vector of the cell data in the problem
254 *
255 */
256 void set_surface_senses( int num_ents[4],
257 std::vector< EntityHandle > entity_map[4],
258 std::vector< side > side_data,
259 std::vector< cell > cell_data );
260
261 /**
262 * creates the group data requried for dagmc, reflecting planes, material assignments etc
263 * @param entity_map, vector of vector of entitiy handles for each dimension
264 *
265 * @returns moab::ErrorCode
266 */
267 ErrorCode setup_group_data( std::vector< EntityHandle > entity_map[4] );
268
269 /**
270 * create a group of a given name, mustkeep track of id
271 * @param group_name, name of the group
272 * @param id, integer id number
273 *
274 * returns the entity handle of the group
275 */
276 EntityHandle create_group( std::string group_name, int id );
277
278 /**
279 * Builds the full MOAB representation of the data, making vertices from coordinates, triangles
280 * from vertices and tets from the same vertices. Tags appropriate to each dataset collection
281 * are applied, triangles are tagged with the surface id and side id they belong to, as well as
282 * tagging the surface with the same data. Tets are similarly tagged only with the Material
283 * number
284 *
285 * @param node_data the node data
286 * @param facet_data, the triangles in the problem
287 * @param tet_data, the tets in the problem
288 * @param surface_map, the map of surface meshset and id numbers
289 *
290 * @return moab::ErrorCode
291 */
292 ErrorCode build_moab( std::vector< node > node_data,
293 std::vector< facet > facet_data,
294 std::vector< tet > tet_data,
295 std::map< int, EntityHandle > surface_map );
296
297 /**
298 * reads the full set of header data
299 *
300 * @param filename, the file to read the data from
301 *
302 * @return moab::Error code
303 */
304 ErrorCode read_header( const char* filename );
305
306 /**
307 * Reads the full set of side data from the file
308 *
309 * @param filename, the file to read all the side data from
310 * @param side data, a vector containing all the read side data
311 *
312 * @return moab::ErrorCode
313 */
314 ErrorCode read_sides( const char* filename, std::vector< side >& side_data );
315
316 /**
317 * Reads the full set of cell data from the file
318 *
319 * @param filename, the file to read all the side data from
320 * @param cell data, a vector containing all the read cell data
321 *
322 * @return moab::ErrorCode
323 */
324 ErrorCode read_cells( const char* filename, std::vector< cell >& cell_data );
325
326 /**
327 * Reads the full set of node data from the file
328 *
329 * @param filename, the file to read all the side data from
330 * @param node data, a vector containing all the read node data
331 *
332 * @return moab::ErrorCode
333 */
334 ErrorCode read_nodes( const char* filename, std::vector< node >& node_data );
335
336 /**
337 * Reads the full set of facet data from the file
338 *
339 * @param filename, the file to read all the side data from
340 * @param facet data, a vector containing all the read facet data
341 *
342 * @return moab::ErrorCode
343 */
344 ErrorCode read_facets( const char* filename, std::vector< facet >& facet_data );
345
346 /**
347 * Reads the full set of tet data from the file
348 *
349 * @param filename, the file to read all the side data from
350 * @param tet data, a vector containing all the read tet data
351 *
352 * @return moab::ErrorCode
353 */
354 ErrorCode read_tets( const char* filename, std::vector< tet >& tet_data );
355
356 /**
357 * Reads the header data into a class member structure
358 *
359 * @param input_file, an open filestream
360 *
361 * @return void
362 */
363 ErrorCode get_header_data( std::ifstream& input_file );
364
365 /**
366 * Reads a single atomic cell data string and populates a cell struct
367 *
368 * @param celldata, a string of read data and
369 *
370 * @return cell, the propulated cell struct
371 */
372 cell get_cell_data( std::string celldata );
373
374 /**
375 * Reads a single atomic side data string and populates a side struct
376 *
377 * @param sidedata, a string of read data and
378 *
379 * @return side, the propulated side struct
380 */
381 side get_side_data( std::string sidedata );
382
383 /**
384 * Reads a single atomic node data string and populates a node struct
385 *
386 * @param sidedata, a string of read data and
387 *
388 * @return node, the propulated node struct
389 */
390 node get_node_data( std::string nodedata );
391
392 /**
393 * Reads a single atomic facet data string and populates a facet struct
394 *
395 * @param facetdata, a string of facet data and
396 *
397 * @return facet, the propulated facet struct
398 */
399 facet get_facet_data( std::string facetdata );
400
401 /**
402 * Reads a single atomic tet data string and populates a tet struct
403 *
404 * @param tetdata, a string of tet data and
405 *
406 * @return tet, the propulated tet struct
407 */
408 tet get_tet_data( std::string tetdata );
409
410 /**
411 * Splits a string into a vector of substrings delimited by split_char
412 *
413 * @param string_to_split, the string that needs splitting into chunks
414 * @param split_char, the character to split the string with
415 *
416 * @return a vector of strings that are delimited by split_char
417 */
418 std::vector< std::string > split_string( std::string string_to_split, char split_char );
419
420 /**
421 * Splits an Attila cellname and populates a boundary structure
422 *
423 * @param attila_cellname, string containing the boundary information
424 *
425 * @return a boundary object
426 */
427 boundary split_name( std::string atilla_cellname );
428
429 /**
430 * Count the number of unique surface numbers in the dataset, also get list of surface numbers
431 * @param side_data, collection of all the side data in the mesh
432 * @param surface_numbers, collection of surface numbers
433 *
434 * returns the number of surface numbers
435 */
436 int count_sides( std::vector< side > side_data, std::vector< int >& surface_numbers );
437
438 // Class Member variables
439 private:
440 headerData header_data;
441 // read mesh interface
442 ReadUtilIface* readMeshIface;
443 // Moab Interface
444 Interface* MBI;
445 // geom tool instance
446 GeomTopoTool* myGeomTool;
447 // tags used in the problem
448 Tag geom_tag, id_tag, name_tag, category_tag, faceting_tol_tag;
449 };
450
451 } // namespace moab
452
453 #endif