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 MshV4GrammarText
22 : qi::grammar<ITERATOR, boost::fusion::adapted::MshFileV4Adapted(),
24 MshV4GrammarText() : MshV4GrammarText::base_type(entry_,
"Msh File") {
26 using phoenix::push_back;
27 using phoenix::reserve;
48 auto size_t_ = qi::ulong_long;
51 quoted_string_ %= lexeme[
'"' >> +(char_ -
'"') >>
'"'];
52 quoted_string_.name(
"string");
53 vec3_ %= double_ > double_ > double_;
54 int_vec_ %= omit[size_t_[(reserve(_val, _1), _a = _1)]] > repeat(_a)[int_];
55 start_comment_ %= !lit(
"$PhysicalNames") >> !lit(
"$Entities") >>
56 !lit(
"$PartitionedEntities") >> !lit(
"$Nodes") >>
57 !lit(
"$Elements") >> !lit(
"$Periodic") >>
58 !lit(
"$GhostElements") >>
59 (lit(
'$') >> (+(char_ - qi::eol)));
60 start_comment_.name(
"Start of Comment");
61 comment_ %= start_comment_[_a = qi::_1] > *(char_ -
'$') >>
"$End" >>
63 comment_.name(
"comment");
64 qi::on_error<qi::fail>(comment_, error_handler_(_1, _2, _3, _4));
68 physical_name_ %= int_ > int_ > quoted_string_;
69 physical_name_.name(
"Physical Name");
70 qi::on_error<qi::fail>(physical_name_, error_handler_(_1, _2, _3, _4));
71 physical_name_vector_ %=
"$PhysicalNames" >
72 omit[size_t_[(reserve(_val, _1), _a = _1)]] >
73 repeat(_a)[physical_name_] >
"$EndPhysicalNames";
74 physical_name_vector_.name(
"$PhyiscalNames");
79 point_entity_ %= int_ > vec3_ > int_vec_;
80 point_entity_.name(
"Point entity");
82 entity_ %= int_ > vec3_ > vec3_ > int_vec_ > int_vec_;
83 entity_.name(
"entity");
85 entities_ %=
"$Entities" >
86 omit[size_t_[(reserve(phoenix::at_c<0>(_val), _1), _a = _1)]] >
87 omit[size_t_[(reserve(phoenix::at_c<1>(_val), _1), _b = _1)]] >
88 omit[size_t_[(reserve(phoenix::at_c<2>(_val), _1), _c = _1)]] >
89 omit[size_t_[(reserve(phoenix::at_c<3>(_val), _1), _d = _1)]] >
90 repeat(_a)[point_entity_] > repeat(_b)[entity_] >
91 repeat(_c)[entity_] > repeat(_d)[entity_] >
"$EndEntities";
92 entities_.name(
"$Entities");
93 qi::on_error<qi::fail>(entities_, error_handler_(_1, _2, _3, _4));
97 omit[size_t_[(reserve(_val, _1), _a = _1)]] >
98 repeat(_a)[int_ > int_];
99 ghost_entities_.name(
"ghost_entities");
100 partitioned_point_entity_ %=
101 int_ > int_ > int_ > int_vec_ > vec3_ > int_vec_;
102 partitioned_point_entity_.name(
"partitioned_point_entity");
105 partitioned_entity_ %= int_ > int_ > int_ > int_vec_ > vec3_ > vec3_ >
107 partitioned_entity_.name(
"partitioned_entity");
109 partitioned_entities2_ %=
110 omit[size_t_[(reserve(at_c<0>(_val), _1), _a = _1)]] >
111 omit[size_t_[(reserve(at_c<1>(_val), _1), _b = _1)]] >
112 omit[size_t_[(reserve(at_c<2>(_val), _1), _c = _1)]] >
113 omit[size_t_[(reserve(at_c<3>(_val), _1), _d = _1)]] >
114 repeat(_a)[partitioned_point_entity_] >
115 repeat(_b)[partitioned_entity_] > repeat(_c)[partitioned_entity_] >
116 repeat(_d)[partitioned_entity_];
117 partitioned_entities2_.name(
"partitioned_entities2");
119 partitioned_entities_ %=
"$PartitionedEntities" > size_t_ >
120 ghost_entities_ > partitioned_entities2_ >
121 "$EndPartitionedEntities";
122 partitioned_entities_.name(
"partitioned_entities");
127 omit[size_t_[(phoenix::resize(at_c<3>(_val), _1), _a = _1, _b = 0)]] >
128 omit[repeat(_a)[size_t_[at_c<0>(at_c<3>(_val)[_b++]) = _1]]] >
130 omit[repeat(_a)[vec3_[at_c<1>(at_c<3>(_val)[_b++]) = _1]]];
131 node_block_.name(
"node_block");
133 nodes_ %=
"$Nodes" > omit[size_t_[(reserve(at_c<3>(_val), _1), _a = _1)]] >
134 size_t_ > size_t_ > size_t_ > repeat(_a)[node_block_] >
136 nodes_.name(
"nodes");
141 omit[size_t_[(reserve(at_c<3>(_val), _1), _a = _1)]] >
142 repeat(_a)[size_t_ > repeat(numNodesAdapted(at_c<2>(_val)))[size_t_]];
143 element_block_.name(
"element_block");
145 elements_ %=
"$Elements" >
146 omit[size_t_[(reserve(at_c<3>(_val), _1), _a = _1)]] >
147 size_t_ > size_t_ > size_t_ > repeat(_a)[element_block_] >
149 elements_.name(
"elements");
153 matrix4d_ %= double_ > double_ > double_ > double_ > double_ > double_ >
154 double_ > double_ > double_ > double_ > double_ > double_ >
155 double_ > double_ > double_ > double_;
156 matrix4d_.name(
"matrix4d");
159 periodic_link_ %= int_ > int_ > int_ > (
'0' | (
"16" > matrix4d_)) >
160 omit[size_t_[(reserve(at_c<4>(_val), _1), _a = _1)]] >
161 repeat(_a)[size_t_ > size_t_];
162 periodic_link_.name(
"periodic_link");
164 periodic_links_ %=
"$Periodic" >
165 omit[size_t_[(reserve(_val, _1), _a = _1)]] >
166 repeat(_a)[periodic_link_] >
"$EndPeriodic";
167 periodic_links_.name(
"periodic_links");
170 ghost_element_ %= size_t_ > int_ >
171 omit[size_t_[(reserve(at_c<2>(_val), _1), _a = _1)]] >
173 ghost_element_.name(
"ghost_element");
175 ghost_elements_ %=
"$GhostElements" >
176 omit[size_t_[(reserve(_val, _1), _a = _1)]] >
177 repeat(_a)[ghost_element_] >
"$EndGhostElements";
178 ghost_elements_.name(
"ghost_elements");
181 entry_ %= *comment_ >> -(physical_name_vector_ >> *comment_) >> entities_ >>
182 *comment_ >> -(partitioned_entities_ >> *comment_) >> nodes_ >>
183 *comment_ >> elements_ >> *comment_ >>
184 -(periodic_links_ >> *comment_) >>
185 -(ghost_elements_ >> *comment_);
186 entry_.name(
"entry");
188 qi::on_error<qi::fail>(entry_, error_handler_(_1, _2, _3, _4));
191 qi::rule<ITERATOR, std::string(), ascii::space_type> quoted_string_;
192 qi::rule<ITERATOR, std::string()> start_comment_;
193 qi::rule<ITERATOR, qi::locals<std::string>, ascii::space_type> comment_;
194 qi::rule<ITERATOR, Eigen::Vector3d(), ascii::space_type> vec3_;
195 qi::rule<ITERATOR, std::vector<int>, qi::locals<std::size_t>,
199 qi::rule<ITERATOR, GMshFileV4::PhysicalName(), ascii::space_type>
201 qi::rule<ITERATOR, std::vector<GMshFileV4::PhysicalName>(),
202 qi::locals<std::size_t>, ascii::space_type>
203 physical_name_vector_;
205 qi::rule<ITERATOR, boost::fusion::adapted::MshFileV4Adapted(),
209 qi::rule<ITERATOR, GMshFileV4::PointEntity(), ascii::space_type>
212 qi::rule<ITERATOR, GMshFileV4::Entity(), ascii::space_type> entity_;
217 std::vector<GMshFileV4::PointEntity>, std::vector<GMshFileV4::Entity>,
218 std::vector<GMshFileV4::Entity>, std::vector<GMshFileV4::Entity>>(),
219 qi::locals<std::size_t, std::size_t, std::size_t, std::size_t>,
223 qi::rule<ITERATOR, std::vector<GMshFileV4::GhostEntity>(),
224 qi::locals<std::size_t>, ascii::space_type>
227 qi::rule<ITERATOR, GMshFileV4::PartitionedPointEntity(), ascii::space_type>
228 partitioned_point_entity_;
230 qi::rule<ITERATOR, GMshFileV4::PartitionedEntity(), ascii::space_type>
234 std::tuple<std::vector<GMshFileV4::PartitionedPointEntity>,
235 std::vector<GMshFileV4::PartitionedEntity>,
236 std::vector<GMshFileV4::PartitionedEntity>,
237 std::vector<GMshFileV4::PartitionedEntity>>(),
238 qi::locals<std::size_t, std::size_t, std::size_t, std::size_t>,
240 partitioned_entities2_;
242 qi::rule<ITERATOR, GMshFileV4::PartitionedEntities(), ascii::space_type>
243 partitioned_entities_;
245 qi::rule<ITERATOR, GMshFileV4::NodeBlock(),
246 qi::locals<std::size_t, std::size_t>, ascii::space_type>
249 qi::rule<ITERATOR, GMshFileV4::Nodes(), qi::locals<std::size_t>,
253 qi::rule<ITERATOR, GMshFileV4::ElementBlock(), qi::locals<std::size_t>,
257 qi::rule<ITERATOR, GMshFileV4::Elements(), qi::locals<std::size_t>,
261 qi::rule<ITERATOR, Eigen::Matrix4d, ascii::space_type> matrix4d_;
263 qi::rule<ITERATOR, GMshFileV4::PeriodicLink(), qi::locals<std::size_t>,
267 qi::rule<ITERATOR, std::vector<GMshFileV4::PeriodicLink>(),
268 qi::locals<std::size_t>, ascii::space_type>
271 qi::rule<ITERATOR, GMshFileV4::GhostElement(), qi::locals<std::size_t>,
275 qi::rule<ITERATOR, std::vector<GMshFileV4::GhostElement>(),
276 qi::locals<std::size_t>, ascii::space_type>
279 struct ErrorHandler {
280 template <
class,
class,
class,
class>
285 template <
class FIRST,
class LAST,
class ERROR_POS,
class WHAT>
286 void operator()(FIRST first, LAST last, ERROR_POS ,
288 std::string input(first, last);
289 if (input.length() > 40) {
290 input = input.substr(0, 40);
292 std::cout <<
"Error in MshFileV4! Expecting " << what <<
" here: \""
293 << input <<
"\"" << std::endl;
296 phoenix::function<ErrorHandler> error_handler_;
302bool ParseGmshFileV4Text(std::string::const_iterator begin,
303 std::string::const_iterator end, GMshFileV4* result) {
305 const MshV4GrammarText<std::string::const_iterator> grammar;
306 return qi::phrase_parse(begin, end, grammar, ascii::space, *result);
Mesh input (from file) and output (in various formats) facilities.