29 #include "boost/lexical_cast.hpp"
42 tok_.set_comment_pattern(
"#");
56 using namespace boost;
59 tok_.set_position( Tokenizer::Position() );
61 if (!
tok_.skip_to(
"$Nodes"))
THROW(ExcMissingSection() << EI_Section(
"$Nodes") << EI_GMSHFile(
tok_.f_name()) );
63 tok_.next_line(
false);
64 n_nodes = lexical_cast<unsigned int> (*
tok_);
66 if (n_nodes == 0)
THROW( ExcZeroNodes() << EI_Position(
tok_.position_msg()) );
69 for (
unsigned int i = 0; i < n_nodes; ++i) {
72 unsigned int id = lexical_cast<unsigned int> (*
tok_); ++
tok_;
74 coords(0) = lexical_cast<double> (*
tok_); ++
tok_;
75 coords(1) = lexical_cast<double> (*
tok_); ++
tok_;
76 coords(2) = lexical_cast<double> (*
tok_); ++
tok_;
82 }
catch (bad_lexical_cast &) {
83 THROW(ExcWrongFormat() << EI_Type(
"number") << EI_TokenizerMsg(
tok_.position_msg()) << EI_MeshFile(
tok_.f_name()) );
85 MessageOut().fmt(
"... {} nodes read. \n", n_nodes);
90 using namespace boost;
93 if (!
tok_.skip_to(
"$Elements"))
THROW(ExcMissingSection() << EI_Section(
"$Elements") << EI_GMSHFile(
tok_.f_name()) );
95 tok_.next_line(
false);
96 unsigned int n_elements = lexical_cast<unsigned int> (*
tok_);
97 if (n_elements == 0)
THROW( ExcZeroElements() << EI_Position(
tok_.position_msg()) );
105 for (
unsigned int i = 0; i < n_elements; ++i) {
107 unsigned int id = lexical_cast<unsigned int>(*
tok_); ++
tok_;
114 unsigned int type = lexical_cast<unsigned int>(*
tok_); ++
tok_;
131 THROW(ExcUnsupportedType() << EI_ElementId(
id) << EI_ElementType(type) << EI_GMSHFile(
tok_.f_name()) );
136 unsigned int n_tags = lexical_cast<unsigned int>(*
tok_);
137 if (n_tags < 2)
THROW( ExcTooManyElementTags() << EI_ElementId(
id) << EI_Position(
tok_.position_msg()) );
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()) );
165 ASSERT_PTR(mesh).error(
"Argument mesh is NULL.\n");
167 using namespace boost;
169 if (!
tok_.skip_to(
"$PhysicalNames",
"$Nodes") )
return;
171 tok_.next_line(
false);
172 unsigned int n_physicals = lexical_cast<unsigned int> (*
tok_);
175 for (
unsigned int i = 0; i < n_physicals; ++i) {
180 unsigned int dim = lexical_cast<unsigned int>(*
tok_); ++
tok_;
181 unsigned int id = lexical_cast<unsigned int>(*
tok_); ++
tok_;
186 }
catch (bad_lexical_cast &) {
187 THROW(ExcWrongFormat() << EI_Type(
"number") << EI_TokenizerMsg(
tok_.position_msg()) << EI_MeshFile(
tok_.f_name()) );
196 using namespace boost;
199 tok_.next_line(
false);
200 unsigned int n_str = lexical_cast<unsigned int>(*
tok_); ++
tok_;
204 tok_.next_line(); n_str--;
208 tok_.next_line(); n_str--;
211 for(;n_str>0;n_str--)
tok_.next_line(
false);
215 unsigned int n_real = lexical_cast<unsigned int>(*
tok_); ++
tok_;
218 tok_.next_line(); n_real--;
221 for(;n_real>0;n_real--)
tok_.next_line(
false);
225 unsigned int n_int = lexical_cast<unsigned int>(*
tok_); ++
tok_;
231 tok_.next_line(); n_int--;
235 tok_.next_line(); n_int--;
239 tok_.next_line(); n_int--;
242 for(;n_int>0;n_int--)
tok_.next_line(
false);
245 }
catch (bad_lexical_cast &) {
246 THROW(ExcWrongFormat() << EI_Type(
"$ElementData header") << EI_TokenizerMsg(
tok_.position_msg()) << EI_MeshFile(
tok_.f_name()) );
253 static int imax = std::numeric_limits<int>::max();
254 unsigned int id, i_row;
255 unsigned int n_bulk_read = 0, n_bdr_read = 0;
257 bulk_el_ids.push_back( imax );
260 bdr_el_ids.push_back( imax );
268 for (i_row = 0; i_row < header.
n_entities; ++i_row)
271 id = boost::lexical_cast<unsigned int>(*
tok_); ++
tok_;
273 while ( std::min(*bulk_id_iter, *bdr_id_iter) < (
int)
id) {
274 if (*bulk_id_iter < *bdr_id_iter) ++bulk_id_iter;
278 if (*bulk_id_iter == (
int)
id) {
281 ++n_bulk_read; ++bulk_id_iter;
282 }
else if (*bdr_id_iter == (
int)
id) {
286 ++n_bdr_read; ++bdr_id_iter;
288 if ( (*bulk_id_iter != imax) | (*bdr_id_iter != imax) )
289 WarningOut().fmt(
"In file '{}', '$ElementData' section for field '{}', time: {}.\nData ID {} is not in order. Skipping rest of data.\n",
294 }
catch (boost::bad_lexical_cast &) {
295 THROW(ExcWrongFormat() << EI_Type(
"$ElementData line") << EI_TokenizerMsg(
tok_.position_msg())
296 << EI_MeshFile(
tok_.f_name()) );
301 LogOut().fmt(
"time: {}; {} bulk and {} boundary entities of field {} read.\n",
311 while ( !
tok_.eof() ) {
312 if (
tok_.skip_to(
"$ElementData") ) {
318 vec.push_back(header);
320 }
else if ( header.
time <=
it->second.back().time ) {
321 WarningOut().fmt(
"Wrong time order: field '{}', time '{}', file '{}'. Skipping this '$ElementData' section.\n",
324 it->second.push_back(header);
329 tok_.set_position( Tokenizer::Position() );
337 if (header_query.
discretization != OutputTime::DiscreteSpace::ELEM_DATA) {
338 if (header_query.
discretization != OutputTime::DiscreteSpace::UNDEFINED && header_query.
discretization != OutputTime::DiscreteSpace::NATIVE_DATA) {
340 "Unsupported discretization for field '{}', time: {} and GMSH format.\nType 'ELEM_DATA' of discretization will be used.\n",
343 header_query.
discretization = OutputTime::DiscreteSpace::ELEM_DATA;
350 THROW( ExcFieldNameNotFound() << EI_FieldName(header_query.
field_name) << EI_MeshFile(
tok_.f_name()));
354 return t * (1.0 + 2.0*numeric_limits<double>::epsilon()) < a.time;
358 table_it->second.end(),
362 if (headers_it == table_it->second.begin()) {
364 << EI_MeshFile(
tok_.f_name()) << EI_Time(header_query.
time));
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Tokenizer tok_
Tokenizer used for reading ASCII file format.
std::string data_section_name_
Store name of field data section specify for type of mesh file.
std::vector< int > const & get_element_ids(bool boundary_domain)
bool has_compatible_mesh_
unsigned int get_boundary_begin() const
Returns start position of boundary data in cache.
virtual void read_ascii_data(Tokenizer &tok, unsigned int n_components, unsigned int i_row)=0
Dedicated class for storing path to input and output files.
void read_element_data(ElementDataCacheBase &data_cache, MeshDataHeader header) override
GmshMeshReader(const FilePath &file_name)
void read_data_header(MeshDataHeader &head)
MeshDataHeader & find_header(HeaderQuery &header_query) override
void read_nodes(Mesh *mesh)
void read_elements(Mesh *mesh)
virtual ~GmshMeshReader()
HeaderTable header_table_
Table with data of ElementData headers.
void make_header_table() override
void read_physical_names(Mesh *mesh) override
void init_element_vector(unsigned int size)
Initialize element_vec_, set size and reset counters of boundary and bulk elements.
void init_node_vector(unsigned int size)
Initialize node_vec_, set size.
unsigned int n_elements() const
void add_physical_name(unsigned int dim, unsigned int id, std::string name)
Add new node of given id and coordinates to mesh.
BCMesh * bc_mesh() const override
Implement MeshBase::bc_mesh(), getter of boundary mesh.
void add_node(unsigned int node_id, arma::vec3 coords)
Add new node of given id and coordinates to mesh.
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.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
#define WarningOut()
Macro defining 'warning' record of log.
#define MessageOut()
Macro defining 'message' record of log.
#define LogOut()
Macro defining 'log' record of log.