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]] > size_t_ >
147 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" > omit[size_t_[reserve(_val, _1), _a = _1]] >
165 repeat(_a)[periodic_link_] >
"$EndPeriodic";
166 periodic_links_.name(
"periodic_links");
169 ghost_element_ %= size_t_ > int_ >
170 omit[size_t_[reserve(at_c<2>(_val), _1), _a = _1]] >
172 ghost_element_.name(
"ghost_element");
174 ghost_elements_ %=
"$GhostElements" >
175 omit[size_t_[reserve(_val, _1), _a = _1]] >
176 repeat(_a)[ghost_element_] >
"$EndGhostElements";
177 ghost_elements_.name(
"ghost_elements");
180 entry_ %= *comment_ >> -(physical_name_vector_ >> *comment_) >> entities_ >>
181 *comment_ >> -(partitioned_entities_ >> *comment_) >> nodes_ >>
182 *comment_ >> elements_ >> *comment_ >>
183 -(periodic_links_ >> *comment_) >>
184 -(ghost_elements_ >> *comment_);
185 entry_.name(
"entry");
187 qi::on_error<qi::fail>(entry_, error_handler_(_1, _2, _3, _4));
190 qi::rule<ITERATOR, std::string(), ascii::space_type> quoted_string_;
191 qi::rule<ITERATOR, std::string()> start_comment_;
192 qi::rule<ITERATOR, qi::locals<std::string>, ascii::space_type> comment_;
193 qi::rule<ITERATOR, Eigen::Vector3d(), ascii::space_type> vec3_;
194 qi::rule<ITERATOR, std::vector<int>, qi::locals<std::size_t>,
198 qi::rule<ITERATOR, GMshFileV4::PhysicalName(), ascii::space_type>
200 qi::rule<ITERATOR, std::vector<GMshFileV4::PhysicalName>(),
201 qi::locals<std::size_t>, ascii::space_type>
202 physical_name_vector_;
204 qi::rule<ITERATOR, boost::fusion::adapted::MshFileV4Adapted(),
208 qi::rule<ITERATOR, GMshFileV4::PointEntity(), ascii::space_type>
211 qi::rule<ITERATOR, GMshFileV4::Entity(), ascii::space_type> entity_;
216 std::vector<GMshFileV4::PointEntity>, std::vector<GMshFileV4::Entity>,
217 std::vector<GMshFileV4::Entity>, std::vector<GMshFileV4::Entity>>(),
218 qi::locals<std::size_t, std::size_t, std::size_t, std::size_t>,
222 qi::rule<ITERATOR, std::vector<GMshFileV4::GhostEntity>(),
223 qi::locals<std::size_t>, ascii::space_type>
226 qi::rule<ITERATOR, GMshFileV4::PartitionedPointEntity(), ascii::space_type>
227 partitioned_point_entity_;
229 qi::rule<ITERATOR, GMshFileV4::PartitionedEntity(), ascii::space_type>
233 std::tuple<std::vector<GMshFileV4::PartitionedPointEntity>,
234 std::vector<GMshFileV4::PartitionedEntity>,
235 std::vector<GMshFileV4::PartitionedEntity>,
236 std::vector<GMshFileV4::PartitionedEntity>>(),
237 qi::locals<std::size_t, std::size_t, std::size_t, std::size_t>,
239 partitioned_entities2_;
241 qi::rule<ITERATOR, GMshFileV4::PartitionedEntities(), ascii::space_type>
242 partitioned_entities_;
244 qi::rule<ITERATOR, GMshFileV4::NodeBlock(),
245 qi::locals<std::size_t, std::size_t>, ascii::space_type>
248 qi::rule<ITERATOR, GMshFileV4::Nodes(), qi::locals<std::size_t>,
252 qi::rule<ITERATOR, GMshFileV4::ElementBlock(), qi::locals<std::size_t>,
256 qi::rule<ITERATOR, GMshFileV4::Elements(), qi::locals<std::size_t>,
260 qi::rule<ITERATOR, Eigen::Matrix4d, ascii::space_type> matrix4d_;
262 qi::rule<ITERATOR, GMshFileV4::PeriodicLink(), qi::locals<std::size_t>,
266 qi::rule<ITERATOR, std::vector<GMshFileV4::PeriodicLink>(),
267 qi::locals<std::size_t>, ascii::space_type>
270 qi::rule<ITERATOR, GMshFileV4::GhostElement(), qi::locals<std::size_t>,
274 qi::rule<ITERATOR, std::vector<GMshFileV4::GhostElement>(),
275 qi::locals<std::size_t>, ascii::space_type>
278 struct ErrorHandler {
279 template <
class,
class,
class,
class>
284 template <
class FIRST,
class LAST,
class ERROR_POS,
class WHAT>
285 void operator()(FIRST first, LAST last, ERROR_POS ,
287 std::string input(first, last);
288 if (input.length() > 40) {
289 input = input.substr(0, 40);
291 std::cout <<
"Error in MshFileV4! Expecting " << what <<
" here: \""
292 << input <<
"\"" << std::endl;
295 phoenix::function<ErrorHandler> error_handler_;
301bool ParseGmshFileV4Text(std::string::const_iterator begin,
302 std::string::const_iterator end, GMshFileV4* result) {
304 MshV4GrammarText<std::string::const_iterator> grammar;
305 return qi::phrase_parse(begin, end, grammar, ascii::space, *result);
Mesh input (from file) and output (in various formats) facilities.