29 #include "boost/lexical_cast.hpp" 41 tok_.set_comment_pattern(
"#");
55 using namespace boost;
58 tok_.set_position( Tokenizer::Position() );
60 if (!
tok_.skip_to(
"$Nodes"))
THROW(ExcMissingSection() << EI_Section(
"$Nodes") << EI_GMSHFile(
tok_.f_name()) );
62 tok_.next_line(
false);
63 n_nodes = lexical_cast<
unsigned int> (*tok_);
65 INPUT_CHECK( n_nodes > 0,
"Zero number of nodes, %s.\n", tok_.position_msg().c_str() );
68 for (
unsigned int i = 0; i < n_nodes; ++i) {
71 unsigned int id = lexical_cast<
unsigned int> (*tok_); ++
tok_;
73 coords(0) = lexical_cast<
double> (*tok_); ++
tok_;
74 coords(1) = lexical_cast<
double> (*tok_); ++
tok_;
75 coords(2) = lexical_cast<
double> (*tok_); ++
tok_;
81 }
catch (bad_lexical_cast &) {
82 THROW(ExcWrongFormat() << EI_Type(
"number") << EI_TokenizerMsg(
tok_.position_msg()) << EI_MeshFile(
tok_.f_name()) );
84 MessageOut().fmt(
"... {} nodes read. \n", n_nodes);
89 using namespace boost;
92 if (!
tok_.skip_to(
"$Elements"))
THROW(ExcMissingSection() << EI_Section(
"$Elements") << EI_GMSHFile(
tok_.f_name()) );
94 tok_.next_line(
false);
95 unsigned int n_elements = lexical_cast<
unsigned int> (*tok_);
96 INPUT_CHECK( n_elements > 0,
"Zero number of elements, %s.\n", tok_.position_msg().c_str());
104 for (
unsigned int i = 0; i < n_elements; ++i) {
106 unsigned int id = lexical_cast<
unsigned int>(*tok_); ++
tok_;
113 unsigned int type = lexical_cast<
unsigned int>(*tok_); ++
tok_;
130 THROW(ExcUnsupportedType() << EI_ElementId(
id) << EI_ElementType(type) << EI_GMSHFile(tok_.f_name()) );
135 unsigned int n_tags = lexical_cast<
unsigned int>(*tok_);
136 INPUT_CHECK(n_tags >= 2,
"At least two element tags have to be defined for element with id=%d, %s.\n",
137 id, tok_.position_msg().c_str());
141 unsigned int region_id = lexical_cast<
unsigned int>(*tok_); ++
tok_;
142 lexical_cast<
unsigned int>(*tok_); ++
tok_;
144 unsigned int partition_id = 0;
145 if (n_tags > 2) { partition_id = lexical_cast<
unsigned int>(*tok_); ++
tok_; }
146 for (
unsigned int ti = 3; ti < n_tags; ti++) ++tok_;
148 for (
unsigned int ni=0; ni<dim+1; ++ni) {
149 node_ids[ni] = lexical_cast<
unsigned int>(*tok_);
152 mesh->
add_element(
id, dim, region_id, partition_id, node_ids);
155 }
catch (bad_lexical_cast &) {
156 THROW(ExcWrongFormat() << EI_Type(
"number") << EI_TokenizerMsg(
tok_.position_msg()) << EI_MeshFile(
tok_.f_name()) );
166 ASSERT(mesh).error(
"Argument mesh is NULL.\n");
168 using namespace boost;
170 if (!
tok_.skip_to(
"$PhysicalNames",
"$Nodes") )
return;
172 tok_.next_line(
false);
173 unsigned int n_physicals = lexical_cast<
unsigned int> (*tok_);
176 for (
unsigned int i = 0; i < n_physicals; ++i) {
181 unsigned int dim = lexical_cast<
unsigned int>(*tok_); ++
tok_;
182 unsigned int id = lexical_cast<
unsigned int>(*tok_); ++
tok_;
187 }
catch (bad_lexical_cast &) {
188 THROW(ExcWrongFormat() << EI_Type(
"number") << EI_TokenizerMsg(
tok_.position_msg()) << EI_MeshFile(
tok_.f_name()) );
197 using namespace boost;
200 tok_.next_line(
false);
201 unsigned int n_str = lexical_cast<
unsigned int>(*tok_); ++
tok_;
205 tok_.next_line(); n_str--;
209 tok_.next_line(); n_str--;
212 for(;n_str>0;n_str--) tok_.next_line(
false);
216 unsigned int n_real = lexical_cast<
unsigned int>(*tok_); ++
tok_;
219 tok_.next_line(); n_real--;
220 head.
time=lexical_cast<
double>(*tok_); ++
tok_;
222 for(;n_real>0;n_real--) tok_.next_line(
false);
226 unsigned int n_int = lexical_cast<
unsigned int>(*tok_); ++
tok_;
232 tok_.next_line(); n_int--;
236 tok_.next_line(); n_int--;
240 tok_.next_line(); n_int--;
243 for(;n_int>0;n_int--) tok_.next_line(
false);
244 head.
position = tok_.get_position();
246 }
catch (bad_lexical_cast &) {
247 THROW(ExcWrongFormat() << EI_Type(
"$ElementData header") << EI_TokenizerMsg(
tok_.position_msg()) << EI_MeshFile(
tok_.f_name()) );
254 bool boundary_domain) {
255 unsigned int id, i_row;
256 unsigned int n_read = 0;
265 for (i_row = 0; i_row < actual_header.
n_entities; ++i_row)
268 id = boost::lexical_cast<
unsigned int>(*tok_); ++
tok_;
270 while (id_iter != el_ids.end() && *id_iter < (int)
id) {
273 if (id_iter == el_ids.end()) {
274 WarningOut().fmt(
"In file '{}', '$ElementData' section for field '{}', time: {}.\nData ID {} not found or is not in order. Skipping rest of data.\n",
279 if (*id_iter == (
int)id) {
280 data_cache.
read_ascii_data(tok_, n_components, (id_iter - el_ids.begin()) );
284 }
catch (boost::bad_lexical_cast &) {
285 THROW(ExcWrongFormat() << EI_Type(
"$ElementData line") << EI_TokenizerMsg(
tok_.position_msg())
286 << EI_MeshFile(
tok_.f_name()) );
289 while (i_row < actual_header.
n_entities)
tok_.next_line(
false), ++i_row;
291 LogOut().fmt(
"time: {}; {} entities of field {} read.\n",
301 while ( !
tok_.eof() ) {
302 if (
tok_.skip_to(
"$ElementData") ) {
308 vec.push_back(header);
310 }
else if ( header.
time <= it->second.back().time ) {
311 WarningOut().fmt(
"Wrong time order: field '{}', time '{}', file '{}'. Skipping this '$ElementData' section.\n",
314 it->second.push_back(header);
319 tok_.set_position( Tokenizer::Position() );
327 if (header_query.
discretization != OutputTime::DiscreteSpace::ELEM_DATA) {
328 if (header_query.
discretization != OutputTime::DiscreteSpace::UNDEFINED && header_query.
discretization != OutputTime::DiscreteSpace::NATIVE_DATA) {
330 "Unsupported discretization for field '{}', time: {} and GMSH format.\nType 'ELEM_DATA' of discretization will be used.\n",
333 header_query.
discretization = OutputTime::DiscreteSpace::ELEM_DATA;
340 THROW( ExcFieldNameNotFound() << EI_FieldName(header_query.
field_name) << EI_MeshFile(
tok_.f_name()));
344 return t * (1.0 + 2.0*numeric_limits<double>::epsilon()) < a.time;
348 table_it->second.end(),
352 if (headers_it == table_it->second.begin()) {
354 << EI_MeshFile(
tok_.f_name()) << EI_Time(header_query.
time));
void make_header_table() override
void read_nodes(Mesh *mesh)
void read_data_header(MeshDataHeader &head)
void init_element_vector(unsigned int size)
Initialize element_vec_, set size and reset counters of boundary and bulk elements.
void add_node(unsigned int node_id, arma::vec3 coords)
Add new node of given id and coordinates to mesh.
void check_compatible_mesh(Mesh &mesh) override
#define MessageOut()
Macro defining 'message' record of log.
virtual ~GmshMeshReader()
void read_physical_names(Mesh *mesh) override
std::string data_section_name_
Store name of field data section specify for type of mesh file.
GmshMeshReader(const FilePath &file_name)
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
void add_physical_name(unsigned int dim, unsigned int id, std::string name)
Add new node of given id and coordinates to mesh.
#define LogOut()
Macro defining 'log' record of log.
virtual void read_ascii_data(Tokenizer &tok, unsigned int n_components, unsigned int i_row)=0
void read_element_data(ElementDataCacheBase &data_cache, MeshDataHeader actual_header, unsigned int n_components, bool boundary_domain) override
#define INPUT_CHECK(i,...)
Debugging macros.
void elements_id_maps(vector< LongIdx > &bulk_elements_id, vector< LongIdx > &boundary_elements_id) const
void create_boundary_elements()
Create boundary elements from data of temporary structure, this method MUST be call after read mesh f...
Dedicated class for storing path to input and output files.
void read_elements(Mesh *mesh)
HeaderTable header_table_
Table with data of ElementData headers.
virtual unsigned int n_elements(bool boundary=false) const
Returns count of boundary or bulk elements.
MeshDataHeader actual_header_
Header of actual loaded data.
#define WarningOut()
Macro defining 'warning' record of log.
void add_element(unsigned int elm_id, unsigned int dim, unsigned int region_id, unsigned int partition_id, std::vector< unsigned int > node_ids)
Add new element of given id to mesh.
bool has_compatible_mesh_
MeshDataHeader & find_header(HeaderQuery &header_query) override
Tokenizer tok_
Tokenizer used for reading ASCII file format.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
std::vector< int > const & get_element_vector(bool boundary_domain)
vector< LongIdx > boundary_elements_id_
void init_node_vector(unsigned int size)
Initialize node_vec_, set size.
vector< LongIdx > bulk_elements_id_