11#include "gmsh_file_v4_detail.h"
16namespace qi = boost::spirit::qi;
17namespace ascii = boost::spirit::ascii;
18namespace phoenix = boost::phoenix;
20template <
class ITERATOR>
21struct MshV4GrammarBinary
22 : qi::grammar<ITERATOR, boost::fusion::adapted::MshFileV4Adapted(),
36 template <
class DWORD,
class QWORD,
class DOUBLE>
37 explicit MshV4GrammarBinary(
const DWORD& dword,
const QWORD& qword,
38 const DOUBLE& bin_double)
39 : MshV4GrammarBinary::base_type(entry_,
"Msh File") {
41 using phoenix::push_back;
42 using phoenix::reserve;
62 auto size_t_ = qi::ulong_long;
65 quoted_string_ %= lexeme[
'"' >> +(char_ -
'"') >>
'"'];
66 quoted_string_.name(
"string");
67 vec3_ %= bin_double > bin_double > bin_double;
69 int_vec_ %= omit[qword[(reserve(_val, _1), _a = _1)]] > repeat(_a)[dword];
70 int_vec_.name(
"int_vec");
71 start_comment_ %= !lit(
"$PhysicalNames") >> !lit(
"$Entities") >>
72 !lit(
"$PartitionedEntities") >> !lit(
"$Nodes") >>
73 !lit(
"$Elements") >> !lit(
"$Periodic") >>
74 !lit(
"$GhostElements") >>
75 (lit(
'$') >> (+(char_ - qi::eol)));
76 start_comment_.name(
"Start of Comment");
77 comment_ %= start_comment_[_a = qi::_1] > *(char_ -
'$') >>
"$End" >>
79 comment_.name(
"comment");
80 qi::on_error<qi::fail>(comment_, error_handler_(_1, _2, _3, _4));
83 physical_name_ %= int_ > int_ > quoted_string_;
84 physical_name_.name(
"Physical Name");
85 qi::on_error<qi::fail>(physical_name_, error_handler_(_1, _2, _3, _4));
86 physical_name_vector_ %=
"$PhysicalNames" >
87 omit[size_t_[(reserve(_val, _1), _a = _1)]] >
88 repeat(_a)[physical_name_] >
"$EndPhysicalNames";
89 physical_name_vector_.name(
"$PhysicalNames");
92 point_entity_ %= dword > vec3_ > int_vec_;
93 point_entity_.name(
"Point entity");
95 entity_ %= dword > vec3_ > vec3_ > int_vec_ > int_vec_;
96 entity_.name(
"entity");
98 entities_ %=
"$Entities\n" >
99 omit[qword[(reserve(phoenix::at_c<0>(_val), _1), _a = _1)]] >
100 omit[qword[(reserve(phoenix::at_c<1>(_val), _1), _b = _1)]] >
101 omit[qword[(reserve(phoenix::at_c<2>(_val), _1), _c = _1)]] >
102 omit[qword[(reserve(phoenix::at_c<3>(_val), _1), _d = _1)]] >
103 repeat(_a)[point_entity_] > repeat(_b)[entity_] >
104 repeat(_c)[entity_] > repeat(_d)[entity_] >
"\n$EndEntities";
105 entities_.name(
"$Entities");
108 ghost_entities_ %= omit[qword[(reserve(_val, _1), _a = _1)]] >
109 repeat(_a)[dword > dword];
110 ghost_entities_.name(
"ghost_entities");
111 partitioned_point_entity_ %=
112 dword > dword > dword > int_vec_ > vec3_ > int_vec_;
113 partitioned_point_entity_.name(
"partitioned_point_entity");
116 partitioned_entity_ %= dword > dword > dword > int_vec_ > vec3_ > vec3_ >
118 partitioned_entity_.name(
"partitioned_entity");
120 partitioned_entities2_ %=
121 omit[qword[(reserve(at_c<0>(_val), _1), _a = _1)]] >
122 omit[qword[(reserve(at_c<1>(_val), _1), _b = _1)]] >
123 omit[qword[(reserve(at_c<2>(_val), _1), _c = _1)]] >
124 omit[qword[(reserve(at_c<3>(_val), _1), _d = _1)]] >
125 repeat(_a)[partitioned_point_entity_] >
126 repeat(_b)[partitioned_entity_] > repeat(_c)[partitioned_entity_] >
127 repeat(_d)[partitioned_entity_];
128 partitioned_entities2_.name(
"partitioned_entities2");
130 partitioned_entities_ %=
"$PartitionedEntities\n" > qword >
131 ghost_entities_ > partitioned_entities2_ >
132 "\n$EndPartitionedEntities";
133 partitioned_entities_.name(
"partitioned_entities");
137 dword > dword > dword >
138 omit[qword[(phoenix::resize(at_c<3>(_val), _1), _a = _1, _b = 0)]] >
139 omit[repeat(_a)[qword[at_c<0>(at_c<3>(_val)[_b++]) = _1]]] >
141 omit[repeat(_a)[vec3_[at_c<1>(at_c<3>(_val)[_b++]) = _1]]];
142 node_block_.name(
"node_block");
144 nodes_ %=
"$Nodes\n" > omit[qword[(reserve(at_c<3>(_val), _1), _a = _1)]] >
145 qword > qword > qword > repeat(_a)[node_block_] >
"\n$EndNodes";
146 nodes_.name(
"nodes");
150 dword > dword > dword >
151 omit[qword[(reserve(at_c<3>(_val), _1), _a = _1)]] >
152 repeat(_a)[qword > repeat(numNodesAdapted(at_c<2>(_val)))[qword]];
153 element_block_.name(
"element_block");
155 elements_ %=
"$Elements\n" >
156 omit[qword[(reserve(at_c<3>(_val), _1), _a = _1)]] > qword >
157 qword > qword > repeat(_a)[element_block_] >
"\n$EndElements";
158 elements_.name(
"elements");
162 matrix4d_ %= bin_double > bin_double > bin_double > bin_double >
163 bin_double > bin_double > bin_double > bin_double >
164 bin_double > bin_double > bin_double > bin_double >
165 bin_double > bin_double > bin_double > bin_double;
166 matrix4d_.name(
"matrix4d");
169 periodic_link_ %= dword > dword > dword >
170 (qword(0) | (qword(16) > matrix4d_)) >
171 omit[qword[(reserve(at_c<4>(_val), _1), _a = _1)]] >
172 repeat(_a)[qword > qword];
173 periodic_link_.name(
"periodic_link");
175 periodic_links_ %=
"$Periodic\n" >
176 omit[qword[(reserve(_val, _1), _a = _1)]] >
177 repeat(_a)[periodic_link_] >
"\n$EndPeriodic";
178 periodic_links_.name(
"periodic_links");
181 ghost_element_ %= qword > dword >
182 omit[qword[(reserve(at_c<2>(_val), _1), _a = _1)]] >
184 ghost_element_.name(
"ghost_element");
186 ghost_elements_ %=
"$GhostElements\n" >
187 omit[qword[(reserve(_val, _1), _a = _1)]] >
188 repeat(_a)[ghost_element_] >
"\n$EndGhostElements";
189 ghost_elements_.name(
"ghost_elements");
192 entry_ %= *comment_ >> -(physical_name_vector_ >> *comment_) >> entities_ >>
193 *comment_ >> -(partitioned_entities_ >> *comment_) >> nodes_ >>
194 *comment_ >> elements_ >> *comment_ >>
195 -(periodic_links_ >> *comment_) >>
196 -(ghost_elements_ >> *comment_);
197 entry_.name(
"entry");
199 qi::on_error<qi::fail>(entry_, error_handler_(_1, _2, _3, _4));
202 qi::rule<ITERATOR, std::string(), ascii::space_type> quoted_string_;
203 qi::rule<ITERATOR, std::string(), ascii::space_type> start_comment_;
204 qi::rule<ITERATOR, qi::locals<std::string>, ascii::space_type> comment_;
205 qi::rule<ITERATOR, Eigen::Vector3d()> vec3_;
206 qi::rule<ITERATOR, std::vector<int>, qi::locals<std::size_t>> int_vec_;
208 qi::rule<ITERATOR, GMshFileV4::PhysicalName(), ascii::space_type>
210 qi::rule<ITERATOR, std::vector<GMshFileV4::PhysicalName>(),
211 qi::locals<std::size_t>, ascii::space_type>
212 physical_name_vector_;
214 qi::rule<ITERATOR, boost::fusion::adapted::MshFileV4Adapted(),
218 qi::rule<ITERATOR, GMshFileV4::PointEntity()> point_entity_;
220 qi::rule<ITERATOR, GMshFileV4::Entity()> entity_;
225 std::vector<GMshFileV4::PointEntity>, std::vector<GMshFileV4::Entity>,
226 std::vector<GMshFileV4::Entity>, std::vector<GMshFileV4::Entity>>(),
227 qi::locals<std::size_t, std::size_t, std::size_t, std::size_t>>
230 qi::rule<ITERATOR, std::vector<GMshFileV4::GhostEntity>(),
231 qi::locals<std::size_t>>
234 qi::rule<ITERATOR, GMshFileV4::PartitionedPointEntity()>
235 partitioned_point_entity_;
237 qi::rule<ITERATOR, GMshFileV4::PartitionedEntity()> partitioned_entity_;
240 std::tuple<std::vector<GMshFileV4::PartitionedPointEntity>,
241 std::vector<GMshFileV4::PartitionedEntity>,
242 std::vector<GMshFileV4::PartitionedEntity>,
243 std::vector<GMshFileV4::PartitionedEntity>>(),
244 qi::locals<std::size_t, std::size_t, std::size_t, std::size_t>>
245 partitioned_entities2_;
247 qi::rule<ITERATOR, GMshFileV4::PartitionedEntities()> partitioned_entities_;
249 qi::rule<ITERATOR, GMshFileV4::NodeBlock(),
250 qi::locals<std::size_t, std::size_t>>
253 qi::rule<ITERATOR, GMshFileV4::Nodes(), qi::locals<std::size_t>> nodes_;
255 qi::rule<ITERATOR, GMshFileV4::ElementBlock(), qi::locals<std::size_t>>
258 qi::rule<ITERATOR, GMshFileV4::Elements(), qi::locals<std::size_t>> elements_;
260 qi::rule<ITERATOR, Eigen::Matrix4d> matrix4d_;
262 qi::rule<ITERATOR, GMshFileV4::PeriodicLink(), qi::locals<std::size_t>>
265 qi::rule<ITERATOR, std::vector<GMshFileV4::PeriodicLink>(),
266 qi::locals<std::size_t>>
269 qi::rule<ITERATOR, GMshFileV4::GhostElement(), qi::locals<std::size_t>>
272 qi::rule<ITERATOR, std::vector<GMshFileV4::GhostElement>(),
273 qi::locals<std::size_t>>
276 struct ErrorHandler {
277 template <
class,
class,
class,
class>
282 template <
class FIRST,
class LAST,
class ERROR_POS,
class WHAT>
283 void operator()(FIRST first, LAST last, ERROR_POS ,
285 std::string input(first, last);
286 if (input.length() > 40) {
287 input = input.substr(0, 40);
289 std::cout <<
"Error in MshFileV4! Expecting " << what <<
" here: \""
290 << input <<
"\"" << std::endl;
293 phoenix::function<ErrorHandler> error_handler_;
299bool ParseGmshFileV4Binary(std::string::const_iterator begin,
300 std::string::const_iterator end,
int one,
301 GMshFileV4* result) {
303 const MshV4GrammarBinary<std::string::const_iterator> grammar(
304 qi::little_dword, qi::little_qword, qi::little_bin_double);
305 return qi::phrase_parse(begin, end, grammar, ascii::space, *result);
307 const MshV4GrammarBinary<std::string::const_iterator> grammar(
308 qi::big_dword, qi::big_qword, qi::big_bin_double);
309 return qi::phrase_parse(begin, end, grammar, ascii::space, *result);
Mesh input (from file) and output (in various formats) facilities.