Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
ReadRTT.hpp
Go to the documentation of this file.
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  std::string contiguity;
148  };
149 
150  struct dimData
151  {
152  std::string coor_units;
153  std::string prob_time_units;
158 
159  int ndim;
161  int nnodes;
163  std::vector< int > nnode_flags;
165 
166  int nsides;
170  std::vector< int > nside_flags;
172 
173  int ncells;
177  std::vector< int > ncell_flags;
179 
180  void print()
181  {
182  std::cout << "dimData: " << std::endl;
183  std::cout << "coor_units: " << coor_units << std::endl;
184  std::cout << "prob_time_units: " << prob_time_units << std::endl;
185  std::cout << "ncell_defs: " << ncell_defs << std::endl;
186  std::cout << std::endl;
187  std::cout << "Node information: " << std::endl;
188  std::cout << "nnodes_max: " << nnodes_max << std::endl;
189  std::cout << "nsides_max: " << nsides_max << std::endl;
190  std::cout << "nnodes_sides_max: " << nnodes_sides_max << std::endl;
191  std::cout << "ndim: " << ndim << std::endl;
192  std::cout << "n_dim_topo: " << n_dim_topo << std::endl;
193  std::cout << "nnodes: " << nnodes << std::endl;
194  std::cout << "nnode_flag_types: " << nnode_flag_types << std::endl;
195  std::cout << "nnode_flags: ";
196  for( size_t i = 0; i < nnode_flags.size(); i++ )
197  {
198  std::cout << nnode_flags[i] << " ";
199  }
200  std::cout << std::endl;
201  std::cout << "nnode_data: " << nnode_data << std::endl;
202 
203  std::cout << std::endl;
204  std::cout << "Side information: " << std::endl;
205  std::cout << "nsides: " << nsides << std::endl;
206  std::cout << "nside_types: " << nside_types << std::endl;
207  std::cout << "side_types: " << side_types << std::endl;
208  std::cout << "nside_flag_types: " << nside_flag_types << std::endl;
209  std::cout << "nside_flags: ";
210  for( size_t i = 0; i < nside_flags.size(); i++ )
211  {
212  std::cout << nside_flags[i] << " ";
213  }
214  std::cout << std::endl;
215  std::cout << "nside_data: " << nside_data << std::endl;
216 
217  std::cout << std::endl;
218  std::cout << "Cell information: " << std::endl;
219  std::cout << "ncells: " << ncells << std::endl;
220  std::cout << "ncell_types: " << ncell_types << std::endl;
221  std::cout << "cell_types: " << cell_types << std::endl;
222  std::cout << "ncell_flag_types: " << ncell_flag_types << std::endl;
223  std::cout << "ncell_flags: ";
224  for( size_t i = 0; i < ncell_flags.size(); i++ )
225  {
226  std::cout << ncell_flags[i] << " ";
227  }
228  std::cout << std::endl;
229  std::cout << "ncell_data: " << ncell_data << std::endl;
230  }
231 
232  void validate()
233  {
234  if( nnode_flag_types > 0 && nnode_flag_types != (int)nnode_flags.size() )
235  {
236  std::cerr << "Warning: nnode_flag_types does not match nnode_flags.size()" << std::endl;
237  }
238 
239  if( nside_flag_types > 0 && nside_flag_types != (int)nside_flags.size() )
240  {
241  std::cerr << "Warning: nside_flag_types does not match nside_flags.size()" << std::endl;
242  }
243 
244  if( ncell_flag_types > 0 && ncell_flag_types != (int)ncell_flags.size() )
245  {
246  std::cerr << "Warning: ncell_flag_types does not match ncell_flags.size()" << std::endl;
247  }
248 
249  if( ncell_flag_types > 1 )
250  {
251  std::cerr << "Warning: Additional flag types will not be read" << std::endl;
252  }
253  }
254  };
255 
256  struct cell_def
257  {
258  int id;
259  std::string name;
260  int nnodes;
261  int nsides;
262 
263  std::vector< int > side_type;
264  std::vector< std::vector< int > > sides_nodes;
265  };
266 
267  // structure to hold sense & vol data
268  struct boundary
269  {
270  int sense;
271  std::string name;
272  };
273 
274  // structure to hold side data
275  struct side
276  {
277  int id;
278  int senses[2];
279  std::string names[2];
280  side() : id( 0 )
281  {
282  senses[0] = senses[1] = 0;
283  names[0] = names[1] = "";
284  }
285  };
286 
287  // structure to hold cell data
288  struct cell
289  {
290  int id;
291  std::string name;
292  cell() : id( 0 ), name( "" ) {}
293  };
294 
295  // structure to hold node data
296  struct node
297  {
298  int id;
299  double x, y, z;
300  node() : id( 0 ), x( 0. ), y( 0. ), z( 0. ) {}
301  };
302 
303  // structure to hold facet data
304  struct facet
305  {
306  int id;
307  int connectivity[3];
308  int side_id;
310  facet() : id( 0 ), side_id( 0 ), surface_number( 0 )
311  {
312  for( int k = 0; k < 3; k++ )
313  connectivity[k] = 0;
314  }
315  };
316 
317  // structure to hold tet data
318  struct tet
319  {
320  int id;
321  int type_id;
322  int connectivity[4];
323  std::vector< int > flag_values;
324  // with c++11 we could use tet(): id(0), connectivity({0}), material_number(0) {}
325  tet() : id( 0 )
326  {
327  for( int k = 0; k < 4; k++ )
328  connectivity[k] = 0;
329  }
330  };
331 
332  // structure to hold a subsection of the RTT input
333  typedef std::map< std::string, std::vector< std::string > > rtt_flags;
334  typedef std::map< std::string, std::vector< cell > > rtt_flags_data;
335 
336  /**
337  * generates the topology of the problem from the already read input data, loops over the 2 and
338  * 3 dimension macrodata that exist from the rtt file, sides = dagmc surfaces, cells = dagmc
339  * cells, creates a meshset for each surface and tags with the id number, and similarly makes a
340  * meshset for dagmc cells and tags with the id number. The surfaces are added to the s surface
341  * map, where the key is the surface ID number (1->N) and (cells and surfaces are added to an
342  * dimesional entity map stored in the class
343  *
344  * @param side_data, vector of side data
345  * @param cell_data, vector of vector of cell data
346  * @param tet_data, vector of tet data
347  * @param surface_map, reference to the surface map of data
348  * @param volume_map, reference to the volume map of data
349  *
350  */
351  ErrorCode generate_topology( std::vector< side > side_data,
352  std::vector< cell > cell_data,
353  std::vector< tet > tet_data,
354  std::map< int, EntityHandle >& surface_map,
355  std::map< int, EntityHandle >& volume_map );
356  /**
357  * Generate parent child links to create DAGMC like structure of surface meshsets being children
358  * of parent cell meshsets. By looping over the surfaces (1->N), look in the description of the
359  * cells that are shared by that surface, and then make the surface the child of the parent
360  * volume. The appropriate sense data will be set later
361  *
362  * @param num_ents[4], array containing the number of surfaces, cells, groups etc
363  * @param entity_map[4], vector of maps containing data by dimension
364  * @param side_data, vector of all the side data in the problem
365  * @param cell_data, vector of the cell data in the problem
366  *
367  */
368  void generate_parent_child_links( int num_ents[4],
369  std::vector< EntityHandle > entity_map[4],
370  std::vector< side > side_data,
371  std::vector< cell > cell_data );
372  /**
373  * Sets the appropriate surface senses for each surface in the problem. By looping through all
374  * the surfaces, we determine from the side_data vector, the volume id's that are shared, then
375  * using 1 to mean +ve sense and -1 to mean -ve sense wrt the volume.
376  *
377  * @param num_ents[4], array containing the number of surfaces, cells, groups etc
378  * @param entity_map[4], vector of maps containing data by dimension
379  * @param side_data, vector of all the side data in the problem
380  * @param cell_data, vector of the cell data in the problem
381  *
382  */
383  void set_surface_senses( int num_ents[4],
384  std::vector< EntityHandle > entity_map[4],
385  std::vector< side > side_data,
386  std::vector< cell > cell_data );
387 
388  /**
389  * creates the group data requried for dagmc, reflecting planes, material assignments etc
390  * @param entity_map, vector of vector of entitiy handles for each dimension
391  * @param tet_data, vector of tet data
392  *
393  * @returns moab::ErrorCode
394  */
395  ErrorCode setup_group_data( std::vector< EntityHandle > entity_map[4],
396  std::vector< tet > tet_data,
397  std::map< int, EntityHandle >& volume_map );
398 
399  /**
400  * create a group of a given name, mustkeep track of id
401  * @param group_name, name of the group
402  * @param id, integer id number
403  *
404  * returns the entity handle of the group
405  */
406  EntityHandle create_group( std::string group_name, int id );
407 
408  /** parse the dimensions of the problem from the file header
409  * @param input_file, an open filestream
410  */
411  ErrorCode parse_dims( std::ifstream& input_file );
412 
413  /** parse the cell definition car
414  * @param input_file, an open filestream
415  */
416  ErrorCode read_cell_defs( std::ifstream& input_file );
417 
418  /**
419  * Builds the full MOAB representation of the data, making vertices from coordinates, triangles
420  * from vertices and tets from the same vertices. Tags appropriate to each dataset collection
421  * are applied, triangles are tagged with the surface id and side id they belong to, as well as
422  * tagging the surface with the same data. Tets are similarly tagged only with the Material
423  * number
424  *
425  * @param node_data the node data
426  * @param facet_data, the triangles in the problem
427  * @param tet_data, the tets in the problem
428  * @param surface_map, the map of surface meshset and id numbers
429  *
430  * @return moab::ErrorCode
431  */
432  ErrorCode build_moab( std::vector< node > node_data,
433  std::vector< facet > facet_data,
434  std::vector< tet > tet_data,
435  std::map< int, EntityHandle > surface_map,
436  std::map< int, EntityHandle > volume_map );
437 
438  /**
439  * Add Metadata to the meshset, this includes the version number and contiguity value
440  * @returns moab::ErrorCode
441  */
442  ErrorCode add_metadata( EntityHandle file_set );
443 
444  /**
445  * reads the full set of header data
446  *
447  * @param filename, the file to read the data from
448  *
449  * @return moab::Error code
450  */
451  ErrorCode read_header( const char* filename );
452 
453  /**
454  * Reads the full set of data from the file
455  *
456  * @param filename, the file to read all the data from
457  * @param n_flags, a vector containing the number of flags
458  * @param flag_id, the flag id to read
459  * @param flags, a map for all the flags from the XX_flags section
460  * @param flag_idx, a map for the index of the flags
461  *
462  * @return moab::ErrorCode
463  */
464  ErrorCode read_all_flags( const char* filename,
465  std::vector< int > n_flags,
466  std::string flag_id,
467  rtt_flags& flags,
468  std::map< std::string, int >& flag_idx );
469 
470  /**
471  * Reads the full set of side data from the file
472  *
473  * @param filename, the file to read all the side data from
474  *
475  * @return moab::ErrorCode
476  */
477  ErrorCode read_side_flags( const char* filename );
478 
479  /**
480  * Process the FACES flag from the side_flags section
481  *
482  * @param side_flags, a vector containing all the read side data
483  * @param side_data, a vector containing all the read side data
484  *
485  * @return moab::ErrorCode
486  */
487  ErrorCode side_process_faces( rtt_flags side_flags, std::vector< side >& side_data );
488 
489  /**
490  * Reads the full set of cell data from the file
491  *
492  * @param filename, the file to read all the side data from
493  *
494  * @return moab::ErrorCode
495  */
496  ErrorCode read_cell_flags( const char* filename );
497 
498  /**
499  * Process the standard flag from the cell_flags section
500  *
501  * @param cell_flags, a vector containing all the read side_flag section
502  * @param key, the key to read
503  * @param cell_data, a vector containing all the read cell data
504  *
505  * @return moab::ErrorCode
506  */
507  ErrorCode cell_process_flag( rtt_flags cell_flags, std::string key );
508 
509  /**
510  * Reads the full set of node data from the file
511  *
512  * @param filename, the file to read all the side data from
513  * @param node data, a vector containing all the read node data
514  *
515  * @return moab::ErrorCode
516  */
517  ErrorCode read_nodes( const char* filename, std::vector< node >& node_data );
518 
519  /**
520  * Reads the full set of facet data from the file
521  *
522  * @param filename, the file to read all the side data from
523  * @param facet data, a vector containing all the read facet data
524  *
525  * @return moab::ErrorCode
526  */
527  ErrorCode read_facets( const char* filename, std::vector< facet >& facet_data );
528 
529  /**
530  * Reads the full set of tet data from the file
531  *
532  * @param filename, the file to read all the side data from
533  * @param tet data, a vector containing all the read tet data
534  *
535  * @return moab::ErrorCode
536  */
537  ErrorCode read_tets( const char* filename, std::vector< tet >& tet_data );
538 
539  /**
540  * Reads the header data into a class member structure
541  *
542  * @param input_file, an open filestream
543  *
544  * @return void
545  */
546  ErrorCode get_header_data( std::ifstream& input_file );
547 
548  /**
549  * Reads a single atomic cell data string and populates a cell struct
550  *
551  * @param celldata, a string of read data and
552  *
553  * @return cell, the propulated cell struct
554  */
555  cell get_cell_data( std::string celldata );
556 
557  /**
558  * Reads a single atomic side data string and populates a side struct
559  *
560  * @param sidedata, a string of read data and
561  *
562  * @return side, the propulated side struct
563  */
564  side get_side_data( std::string sidedata );
565 
566  /**
567  * Reads a single atomic node data string and populates a node struct
568  *
569  * @param sidedata, a string of read data and
570  *
571  * @return node, the propulated node struct
572  */
573  node get_node_data( std::string nodedata );
574 
575  /**
576  * Reads a single atomic facet data string and populates a facet struct
577  *
578  * @param facetdata, a string of facet data and
579  *
580  * @return facet, the propulated facet struct
581  */
582  facet get_facet_data( std::string facetdata );
583 
584  /**
585  * Reads a single atomic tet data string and populates a tet struct
586  *
587  * @param tetdata, a string of tet data and
588  *
589  * @return tet, the propulated tet struct
590  */
591  tet get_tet_data( std::string tetdata );
592 
593  /**
594  * @brief Get the material ref flag object
595  *
596  * @return std::string
597  */
598  std::string get_material_ref_flag();
599 
600  /**
601  * @brief Get the volume ref flag object
602  *
603  * @return std::string
604  */
605  std::string get_volume_ref_flag();
606 
607  /**
608  * @brief Get the max name size object
609  *
610  * @param cell_data, vector of cell data
611  * @return int, the max name size
612  */
613  int get_max_name_size( std::vector< cell > cell_data );
614 
615  /**
616  * Splits a string into a vector of substrings delimited by split_char
617  *
618  * @param string_to_split, the string that needs splitting into chunks
619  * @param split_char, the character to split the string with
620  *
621  * @return a vector of strings that are delimited by split_char
622  */
623  std::vector< std::string > split_string( std::string string_to_split, char split_char );
624 
625  /**
626  * Splits an Attila cellname and populates a boundary structure
627  *
628  * @param attila_cellname, string containing the boundary information
629  *
630  * @return a boundary object
631  */
632  boundary split_name( std::string atilla_cellname );
633 
634  /**
635  * Count the number of unique surface numbers in the dataset, also get list of surface numbers
636  * @param side_data, collection of all the side data in the mesh
637  * @param surface_numbers, collection of surface numbers
638  *
639  * returns the number of surface numbers
640  */
641  int count_sides( std::vector< side > side_data, std::vector< int >& surface_numbers );
642 
643  void create_facets( const std::vector< facet >& facet_data,
644  const std::map< int, EntityHandle >& surface_map,
645  Range& mb_coords,
646  EntityHandle file_set );
647  ErrorCode create_material_group( const std::string& material_name, int material_id, EntityHandle& handle );
648 
649  // Class Member variables
650  private:
653 
654  // Cell Datas read from the cell_flags section
655  rtt_flags_data cell_flag_datas; //vector of cell for each cell sub-flag
656  std::map< std::string, std::map< int, int > >
657  cell_flag_indexes; // map of indexes for each element of the cell_flag_datas
658  std::map< std::string, int > cell_flag_idx; // map the order of each sub-cell flag
659 
660  // Side Datas read from the side_flags section
662  std::map< std::string, std::map< int, int > > side_flag_indexes;
663  std::map< std::string, int > side_flag_idx;
664 
665  // Data from the cell_def section
666  std::map< int, cell_def > cell_def_data; // definition of the types of cells
667  std::vector< cell > cell_data;
668  std::map< int, int > cell_data_idx;
669 
670  std::vector< side > side_data;
671  // read mesh interface
673  // Moab Interface
675  // geom tool instance
677  // tags used in the problem
679 };
680 
681 } // namespace moab
682 
683 #endif