LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
Loading...
Searching...
No Matches
gmsh_file_v2.cc
1
10#include "gmsh_file_v2.h"
11
12#include <boost/fusion/include/adapt_struct.hpp>
13#include <boost/fusion/include/adapt_struct_named.hpp>
14#include <boost/fusion/include/boost_array.hpp>
15#include <boost/fusion/include/io.hpp>
16#include <boost/fusion/include/std_pair.hpp>
17#include <boost/fusion/iterator.hpp>
18#include <boost/fusion/support/category_of.hpp>
19#include <boost/fusion/support/iterator_base.hpp>
20#include <boost/fusion/support/tag_of.hpp>
21#include <boost/fusion/support/tag_of_fwd.hpp>
22#include <boost/mpl/minus.hpp>
23#include <boost/phoenix/core.hpp>
24#include <boost/phoenix/function/adapt_function.hpp>
25#include <boost/phoenix/object.hpp>
26#include <boost/phoenix/operator.hpp>
27#include <boost/phoenix/stl.hpp>
28#include <boost/spirit/include/qi.hpp>
29#include <boost/spirit/include/qi_binary.hpp>
30
31#include "eigen_fusion_adapter.h"
32
33using size_type = lf::mesh::Mesh::size_type;
34
35namespace lf::io {
36
38std::ostream& operator<<(std::ostream& stream, GMshFileV2::ElementType et) {
39 switch (et) {
40 default:
41 break;
43 stream << "EDGE2";
44 break;
46 stream << "TRIA3";
47 break;
49 stream << "QUAD4";
50 break;
52 stream << "TET4";
53 break;
55 stream << "HEX8";
56 break;
58 stream << "PRISM6";
59 break;
61 stream << "PYRAMID5";
62 break;
64 stream << "EDGE3";
65 break;
67 stream << "TRIA6";
68 break;
70 stream << "QUAD9";
71 break;
73 stream << "TET10";
74 break;
76 stream << "HEX27";
77 break;
79 stream << "PRISM18";
80 break;
82 stream << "PYRAMID14";
83 break;
85 stream << "POINT";
86 break;
88 stream << "QUAD8";
89 break;
91 stream << "HEX20";
92 break;
94 stream << "PRISM15";
95 break;
97 stream << "PYRAMID13";
98 break;
100 stream << "TRIA9";
101 break;
103 stream << "TRIA10";
104 break;
106 stream << "TRIA12";
107 break;
109 stream << "TRIA15";
110 break;
112 stream << "TRIA15_5";
113 break;
115 stream << "TRIA21";
116 break;
118 stream << "EDGE4";
119 break;
121 stream << "EDGE5";
122 break;
124 stream << "EDGE6";
125 break;
127 stream << "TET20";
128 break;
130 stream << "TET35";
131 break;
133 stream << "TET56";
134 break;
136 stream << "HEX64";
137 break;
139 stream << "HEX125";
140 break;
141 }
142 return stream;
143}
144
146std::ostream& operator<<(std::ostream& stream, const GMshFileV2& mf) {
147 stream << "GMSH FILE: Ver. " << mf.VersionNumber
148 << (mf.IsBinary ? "(Binary)" : "(Text)")
149 << ", size of double = " << mf.DoubleSize << '\n';
150 stream << "=======================================================" << '\n';
151 stream << "PHYSICAL ENTITIES (Dimension, Number, Name):" << '\n';
152 for (const auto& pe : mf.PhysicalEntities) {
153 stream << " " << pe.Dimension << "\t , " << pe.Number << "\t , " << pe.Name
154 << '\n';
155 }
156 stream << "NODES (Number, coords)" << '\n';
157 for (const auto& n : mf.Nodes) {
158 stream << " " << n.first << "\t , " << n.second.transpose() << '\n';
159 }
160 stream << "ELEMENTS (Number, Type, PhysicalEntity Nr, ElementaryEntityNr, "
161 "Mesh partitions to which it belongs, Node numbers in it)"
162 << '\n';
163 for (const auto& e : mf.Elements) {
164 stream << " " << e.Number << "\t " << e.Type << '\t' << e.PhysicalEntityNr
165 << "\t" << e.ElementaryEntityNr << "\t";
166 for (auto p : e.MeshPartitions) {
167 stream << p << ", ";
168 }
169 stream << '\t';
170 for (auto n : e.NodeNumbers) {
171 stream << n << ", ";
172 }
173 stream << '\n';
174 }
175 stream << '\n';
176 stream << "PERIODIC ENTITIES:" << '\n';
177 for (const auto& pe : mf.Periodic) {
178 std::cout << " dim=" << pe.Dimension
179 << ", slaveNr=" << pe.ElementarySlaveNr
180 << ", masterNr=" << pe.ElementaryMasterNr << '\n';
181 for (auto nm : pe.NodeMapping) {
182 std::cout << " " << nm.first << " <-> " << nm.second << '\n';
183 }
184 }
185 return stream;
186}
187
190 switch (et) {
191 default:
192 break;
194 return 2;
196 return 3;
199 return 4;
201 return 8;
203 return 6;
205 return 5;
207 return 3;
209 return 6;
211 return 9;
213 return 10;
215 return 27;
217 return 18;
219 return 14;
221 return 1;
223 return 8;
225 return 20;
227 return 15;
229 return 13;
231 return 9;
233 return 10;
235 return 12;
238 return 15;
240 return 21;
242 return 4;
244 return 5;
246 return 6;
248 return 20;
250 return 35;
252 return 56;
254 return 64;
256 return 125;
257 }
258 LF_VERIFY_MSG(false, "unknown Gmsh element type");
259 // Make compiler happy:
260 return 0;
261}
262
264 switch (et) {
266 return base::RefEl::kPoint();
267
273 return base::RefEl::kSegment();
274
283 return base::RefEl::kTria();
284
288 return base::RefEl::kQuad();
289
306 default:
307 LF_VERIFY_MSG(
308 false, "Reference element not supported for GmshElement type " << et);
309 }
310}
311
314 switch (et) {
316 return 0;
322 return 1;
334 return 2;
351 return 3;
352 default:
353 LF_VERIFY_MSG(false, "Unknown GmshElement Type.");
354 }
355 // Make compiler happy:
356 return -1;
357}
358} // namespace lf::io
359
360// Boost Fusion Adaptions (needed so boost spirit can parse directly into
361// GMshFileV2 struct)
363BOOST_FUSION_ADAPT_STRUCT(lf::io::GMshFileV2::PhysicalEntity,
364 (int, Dimension)(int, Number)(std::string, Name));
365
366BOOST_FUSION_ADAPT_STRUCT(
368 (size_type, Number)(lf::io::GMshFileV2::ElementType,
369 Type)(int, PhysicalEntityNr)(int, ElementaryEntityNr)(
370 std::vector<int>, MeshPartitions)(std::vector<size_type>, NodeNumbers));
371
373using nodeMapping_t = std::pair<size_type, size_type>;
374
375BOOST_FUSION_ADAPT_STRUCT(lf::io::GMshFileV2::PeriodicEntity,
376 (int, Dimension)(int, ElementarySlaveNr)(
377 int,
378 ElementaryMasterNr)(std::vector<nodeMapping_t>,
379 NodeMapping));
380
382using nodePair_t = std::pair<size_type, Eigen::Vector3d>;
383
386// NOLINTNEXTLINE
387BOOST_FUSION_ADAPT_STRUCT_NAMED(
388 lf::io::GMshFileV2, MshFileAdapted, // NOLINT
389 //(double, VersionNumber)
390 //(bool, IsBinary)
391 //(int, DoubleSize)
392 (std::vector<lf::io::GMshFileV2::PhysicalEntity>,
393 PhysicalEntities)(std::vector<nodePair_t>, Nodes)(
394 std::vector<lf::io::GMshFileV2::Element>,
395 Elements)(std::vector<lf::io::GMshFileV2::PeriodicEntity>, Periodic));
396
398namespace boost::spirit::traits {
399/*template<>
400struct transform_attribute<hydi::io::MshFile::ElementType, int, qi::domain> {
401 using type = int&;
402 static int& pre(hydi::io::MshFile::ElementType& d) { return (int&)d; }
403 static void post(hydi::io::MshFile::ElementType& dval, const int& attr) {}
404 static void fail(hydi::io::MshFile::ElementType&) {}
405};*/
406
407template <class Enum, typename RawValue>
408 requires(std::is_enum_v<Enum> && !std::is_same_v<Enum, RawValue>)
409struct assign_to_attribute_from_value<Enum, RawValue> {
410 static void call(RawValue const& raw, Enum& cat) {
411 cat = static_cast<Enum>(raw);
412 }
413};
414
415} // namespace boost::spirit::traits
417
418namespace lf::io {
419namespace /*Anonymous*/ {
420
421namespace qi = boost::spirit::qi;
422namespace ascii = boost::spirit::ascii;
423namespace phoenix = boost::phoenix;
424
426struct gmshElementType : qi::symbols<char, unsigned> {
427 gmshElementType() {
428 for (const auto& et : GMshFileV2::AllElementTypes) {
429 add(std::to_string(static_cast<int>(et)), static_cast<int>(et));
430 }
431 }
432};
433
434// NOLINTNEXTLINE
435BOOST_PHOENIX_ADAPT_FUNCTION(int, numNodesAdapted, NumNodes, 1);
436
438template <class ITERATOR>
439struct MshGrammarText
440 : qi::grammar<ITERATOR, boost::fusion::adapted::MshFileAdapted(),
441 ascii::space_type> {
442 MshGrammarText(
443 qi::rule<ITERATOR, std::pair<size_type, Eigen::Vector3d>()> nodeRule,
444 qi::rule<ITERATOR, std::vector<GMshFileV2::Element>(),
445 qi::locals<size_type, int, int, int, size_type>>
446 elementGroup)
447 : MshGrammarText::base_type(start_, "Msh File"),
448 node_(nodeRule),
449 elementGroup_(elementGroup) {
450 using phoenix::push_back;
451 using phoenix::reserve;
452 using phoenix::val;
453 using qi::_val;
454 using qi::char_;
455 using qi::double_;
456 using qi::eps;
457 using qi::int_;
458 using qi::lexeme;
459 using qi::lit;
460 using qi::omit;
461 using qi::repeat;
462 using qi::labels::_1;
463 using qi::labels::_2;
464 using qi::labels::_3;
465 using qi::labels::_4;
466 using qi::labels::_a;
467
468 // General Parsers:
469 quotedString_ %= lexeme['"' >> +(char_ - '"') >> '"'];
470 quotedString_.name("string");
471 startComment_ %= !lit("$PhysicalNames") >> !lit("$Nodes") >>
472 !lit("$Elements") >> !lit("$Periodic") >>
473 (lit('$') >> (+(char_ - qi::eol)));
474 startComment_.name("Start of Comment");
475 comment_ %=
476 startComment_[_a = qi::_1] > *(char_ - '$') >> "$End" >> qi::string(_a);
477 comment_.name("comment");
478 qi::on_error<qi::fail>(comment_,
479 errorHandler_(qi::_1, qi::_2, qi::_3, qi::_4));
480
481 // Physical Entities:
482 physicalEntity_ %= int_ > int_ > quotedString_; // NOLINT
483 physicalEntity_.name("Physical Entity Entry");
484 qi::on_error<qi::fail>(physicalEntity_,
485 errorHandler_(qi::_1, qi::_2, qi::_3, qi::_4));
486 physicalEntityGroup_ %= "$PhysicalNames" >
487 omit[int_[(reserve(_val, qi::_1), _a = qi::_1)]] >
488 repeat(_a)[physicalEntity_] > "$EndPhysicalNames";
489 physicalEntityGroup_.name("$Physical Entity Section");
490 qi::on_error<qi::fail>(physicalEntityGroup_,
491 errorHandler_(qi::_1, qi::_2, qi::_3, qi::_4));
492
493 // Nodes:
494 nodeGroup_ %= "$Nodes" > qi::eol >
495 omit[qi::uint_[(reserve(_val, qi::_1), _a = qi::_1)]] >
496 qi::eol > repeat(_a)[node_] > -qi::eol > "$EndNodes";
497 nodeGroup_.name("$Node Section");
498 qi::on_error<qi::fail>(node_,
499 errorHandler_(qi::_1, qi::_2, qi::_3, qi::_4));
500 qi::on_error<qi::fail>(nodeGroup_,
501 errorHandler_(qi::_1, qi::_2, qi::_3, qi::_4));
502
503 // Elements:
504 qi::on_error<qi::fail>(elementGroup_,
505 errorHandler_(qi::_1, qi::_2, qi::_3, qi::_4));
506
507 // Periodic entities:
508 periodicEntityNodeMapping_ =
509 omit[qi::uint_[(reserve(_val, qi::_1), _a = qi::_1)]] >
510 repeat(_a)[qi::uint_ > qi::uint_]; // NOLINT
511 periodicEntityNodeMapping_.name("slave-master node mapping");
512 qi::on_error<qi::fail>(periodicEntityNodeMapping_,
513 errorHandler_(qi::_1, qi::_2, qi::_3, qi::_4));
514 periodicEntity_ =
515 int_ > int_ > int_ > periodicEntityNodeMapping_; // NOLINT
516 periodicEntity_.name("periodic entity");
517 qi::on_error<qi::fail>(periodicEntity_,
518 errorHandler_(qi::_1, qi::_2, qi::_3, qi::_4));
519 periodicEntityGroup_ =
520 "$Periodic" > omit[qi::uint_[(reserve(_val, qi::_1), _a = qi::_1)]] >
521 repeat(_a)[periodicEntity_] > "$EndPeriodic";
522 periodicEntityGroup_.name("periodic entity section");
523 qi::on_error<qi::fail>(periodicEntityGroup_,
524 errorHandler_(qi::_1, qi::_2, qi::_3, qi::_4));
525
526 // The whole file:
527 start_ %= *comment_ >> -(physicalEntityGroup_ >> *comment_) >> nodeGroup_ >>
528 *comment_ >> elementGroup_ >> *comment_ >>
529 -(periodicEntityGroup_ >> *comment_);
530 start_.name("beginning of file");
531 qi::on_error<qi::fail>(start_,
532 errorHandler_(qi::_1, qi::_2, qi::_3, qi::_4));
533 }
534
535 private:
536 qi::rule<ITERATOR, std::string(), ascii::space_type> quotedString_;
537 qi::rule<ITERATOR, std::string()> startComment_;
538 qi::rule<ITERATOR, qi::locals<std::string>, ascii::space_type> comment_;
539
540 qi::rule<ITERATOR, GMshFileV2::PhysicalEntity(), ascii::space_type>
541 physicalEntity_;
542 qi::rule<ITERATOR, std::vector<GMshFileV2::PhysicalEntity>(),
543 qi::locals<size_type>, ascii::space_type>
544 physicalEntityGroup_;
545
546 qi::rule<ITERATOR, std::pair<size_type, Eigen::Vector3d>()> node_;
547 qi::rule<ITERATOR, std::vector<std::pair<size_type, Eigen::Vector3d>>(),
548 qi::locals<size_type>>
549 nodeGroup_;
550
553 qi::rule<ITERATOR, std::vector<GMshFileV2::Element>(),
554 qi::locals<size_type, int, int, int, size_type>>
555 elementGroup_;
556
557 qi::rule<ITERATOR, std::vector<std::pair<size_type, size_type>>(),
558 qi::locals<size_type>, ascii::space_type>
559 periodicEntityNodeMapping_;
560 qi::rule<ITERATOR, GMshFileV2::PeriodicEntity(), ascii::space_type>
561 periodicEntity_;
562 qi::rule<ITERATOR, std::vector<GMshFileV2::PeriodicEntity>(),
563 qi::locals<size_type>, ascii::space_type>
564 periodicEntityGroup_;
565
566 qi::rule<ITERATOR, boost::fusion::adapted::MshFileAdapted(),
567 ascii::space_type>
568 start_;
569
570 struct ErrorHandler {
571 template <class, class, class, class>
572 struct result {
573 using type = void;
574 };
575
576 template <class FIRST, class LAST, class ERROR_POS, class WHAT>
577 void operator()(FIRST first, LAST last, ERROR_POS /*errorPos*/,
578 WHAT what) const {
579 std::string input(first, last);
580 if (input.length() > 40) {
581 input = input.substr(0, 40);
582 }
583 std::cout << "Error in MshFile! Expecting " << what << " here: \""
584 << input << "\"" << std::endl;
585 }
586 };
587 phoenix::function<ErrorHandler> errorHandler_;
588};
589
590} // namespace
591
592const std::vector<GMshFileV2::ElementType> GMshFileV2::AllElementTypes{
593 ElementType::EDGE2, ElementType::TRIA3, ElementType::QUAD4,
594 ElementType::TET4, ElementType::HEX8, ElementType::PRISM6,
595 ElementType::PYRAMID5, ElementType::EDGE3, ElementType::TRIA6,
596 ElementType::QUAD9, ElementType::TET10, ElementType::HEX27,
597 ElementType::PRISM18, ElementType::PYRAMID14, ElementType::POINT,
598 ElementType::QUAD8, ElementType::HEX20, ElementType::PRISM15,
599 ElementType::PYRAMID13, ElementType::TRIA9, ElementType::TRIA10,
600 ElementType::TRIA12, ElementType::TRIA15, ElementType::TRIA15_5,
601 ElementType::TRIA21, ElementType::EDGE4, ElementType::EDGE5,
602 ElementType::EDGE6, ElementType::TET20, ElementType::TET35,
603 ElementType::TET56, ElementType::HEX64, ElementType::HEX125};
604
605GMshFileV2 readGmshFileV2(std::string::const_iterator begin,
606 std::string::const_iterator end,
607 const std::string& version, bool is_binary,
608 int size_t_size, int one,
609 const std::string& filename) {
610 LF_VERIFY_MSG(version == "2.2",
611 "Version " << version << " not supported by readGmshFileV2");
612 LF_ASSERT_MSG(size_t_size == 8, "Size of std::size_t must be 8.");
613
614 GMshFileV2 result;
615 result.IsBinary = is_binary;
616 result.VersionNumber = version;
617 result.DoubleSize = size_t_size;
618
619 // Parse the rest of the document
621
622 // Setup parsers for node/element sections (which are different depending on
623 // binary/non-binary files):
624 //
625 // Note vec3 has no skipper because it may be used inside lexeme and lexeme
626 // can only use parsers without skippers!
627 // http://boost-spirit.com/home/2010/02/24/parsing-skippers-and-skipping-parsers/
628 // (see comment section)
629 using iterator_t = std::string::const_iterator;
630 qi::rule<iterator_t, Eigen::Vector3d> vec3;
631 qi::rule<iterator_t, std::pair<size_type, Eigen::Vector3d>()> node;
632 qi::rule<iterator_t, GMshFileV2::Element(), qi::locals<int>> elementText;
633 qi::rule<iterator_t, GMshFileV2::Element(GMshFileV2::ElementType, int, int)>
634 elementBin;
635 qi::rule<iterator_t, std::vector<GMshFileV2::Element>(),
636 qi::locals<size_type, int, int, int, size_type>>
637 elementGroup;
638
639 using phoenix::reserve;
640 using qi::omit;
641 using qi::repeat;
642 using qi::labels::_a;
643 using qi::labels::_b;
644 using qi::labels::_c;
645 using qi::labels::_d;
646 using qi::labels::_e;
647 using qi::labels::_r1;
648 using qi::labels::_r2;
649 using qi::labels::_r3;
650 using qi::labels::_val;
651
652 if (!is_binary) {
653 // Text file
654 vec3 = qi::double_ >> ' ' >> qi::double_ >> ' ' >> qi::double_;
655 node = qi::uint_ >> ' ' >> vec3 >> qi::eol;
656 elementText %= qi::int_ > ' ' > qi::int_ > ' ' >
657 qi::omit[qi::int_[qi::_a = qi::_1]] > ' ' > qi::int_ > ' ' >
658 qi::int_ > ' ' >
659 ((qi::eps(_a > 2) >> omit[qi::int_] >> ' ') || qi::eps) >
660 qi::repeat(qi::_a - 3)[qi::int_ >> ' '] > (qi::uint_ % ' ') >
661 *(qi::blank) > qi::eol;
662 elementGroup %= "$Elements" > qi::eol >
663 qi::omit[qi::uint_[(phoenix::reserve(qi::_val, qi::_1),
664 qi::_a = qi::_1)]] > qi::eol >
665 qi::repeat(qi::_a)[elementText] > "$EndElements";
666 } else if (is_binary && one == 1) {
667 // Binary File Little Endian
668 // std::cout << "little endian" << std::endl;
669 vec3 %=
670 qi::little_bin_double >> qi::little_bin_double >> qi::little_bin_double;
671 node %= qi::no_skip[qi::little_dword >> vec3];
672 elementBin %= qi::little_dword >> qi::attr(_r1) >> qi::little_dword >>
673 qi::little_dword >>
674 ((qi::eps(_r2 > 2) >> omit[qi::little_dword]) || qi::eps) >>
675 qi::repeat(_r2 - 3)[qi::little_dword] >>
676 qi::repeat(_r3)[qi::little_dword];
677 elementGroup %=
678 "$Elements" >> qi::eol >> qi::eps[_e = 0] >>
679 omit[qi::uint_[(reserve(_val, qi::_1), _a = qi::_1)]] >>
680 qi::eol // # Elements in total
681 >>
682 omit[*((qi::eps(_e < _a) >> qi::little_dword[_b = qi::_1] >>
683 qi::little_dword[_c = qi::_1] >>
684 qi::little_dword[_d = qi::_1] // elements-header-binary
685 >> repeat(_c)[elementBin(
686 phoenix::static_cast_<GMshFileV2::ElementType>(_b), _d,
687 numNodesAdapted(
688 phoenix::static_cast_<GMshFileV2::ElementType>(
689 _b)))[phoenix::push_back(_val, qi::_1)]]) >>
690 qi::eps[_e += _c])] // elements-binary
691 >> qi::eol >> "$EndElements";
692 } else {
693 // std::cout << "big endian" << std::endl;
694 // Binary File Big Endian
695 vec3 %= qi::big_bin_double >> qi::big_bin_double >> qi::big_bin_double;
696 node %= qi::no_skip[qi::big_dword >> vec3];
697 elementBin %=
698 qi::big_dword >> qi::attr(_r1) >> qi::big_dword >> qi::big_dword >>
699 ((qi::eps(_r2 > 2) >> omit[qi::big_dword]) || qi::eps) >>
700 qi::repeat(_r2 - 3)[qi::big_dword] >> qi::repeat(_r3)[qi::big_dword];
701 elementGroup %=
702 "$Elements" >> qi::eol >> qi::eps[_e = 0] >>
703 omit[qi::uint_[(reserve(_val, qi::_1), _a = qi::_1)]] >>
704 qi::eol // # Elements in total
705 >>
706 omit[*((qi::eps(_e < _a) >> qi::big_dword[_b = qi::_1] >>
707 qi::big_dword[_c = qi::_1] >>
708 qi::big_dword[_d = qi::_1] // elements-header-binary
709 >> repeat(_c)[elementBin(
710 phoenix::static_cast_<GMshFileV2::ElementType>(_b), _d,
711 numNodesAdapted(
712 phoenix::static_cast_<GMshFileV2::ElementType>(
713 _b)))[phoenix::push_back(_val, qi::_1)]]) >>
714 qi::eps[_e += _c])] // elements-binary
715 >> qi::eol >> "$EndElements";
716 }
717
719 vec3.name("vec3");
720 node.name("node");
721 elementText.name("element");
722 elementBin.name("element");
723 elementGroup.name("ElementSection");
724
725 // Finally parse everything:
726 const MshGrammarText<iterator_t> mshGrammar(node, elementGroup);
727 const bool r = qi::phrase_parse(begin, end, mshGrammar, ascii::space, result);
728
729 // if (r && iter == end) std::cout << "Parsing succeeded" << std::endl;
730 // else if (r) std::cout << "Parsing partially succeeded" << std::endl;
731 // std::cout << result << std::endl;
732
733 LF_VERIFY_MSG(r, "Could not parse file " << filename);
734 LF_VERIFY_MSG(begin == end, "Could not parse all of file " << filename);
735
736 return result;
737}
738
739} // namespace lf::io
Represents a reference element with all its properties.
Definition ref_el.h:109
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
Definition ref_el.h:153
static constexpr RefEl kPoint()
Returns the (0-dimensional) reference point.
Definition ref_el.h:144
static constexpr RefEl kTria()
Returns the reference triangle.
Definition ref_el.h:161
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
Definition ref_el.h:169
lf::base::size_type size_type
Mesh input (from file) and output (in various formats) facilities.
GMshFileV2 readGmshFileV2(std::string::const_iterator begin, std::string::const_iterator end, const std::string &version, bool is_binary, int size_t_size, int one, const std::string &filename)
Read a *.msh file from disk and copy it's contents into the MshFile Datastructure.
int DimOf(GMshFileV2::ElementType et)
Dimension of the GmshElement type.
base::RefEl RefElOf(GMshFileV2::ElementType et)
Reference element type of a GmshElementType.
std::ostream & operator<<(std::ostream &stream, GMshFileV2::ElementType et)
Output the element type onto the console:
size_type NumNodes(GMshFileV2::ElementType et)
Number of nodes that this element type has.
Represents a mesh volume/surface/line/point.
Describes how 2 elementary entities are identified with each to represent periodic boundaries.
Represents a physical entity as defined in gmsh. In GMSH a Physical entity is created through one of ...
A representation of a .msh file (V2) in a c++ data structure.
std::string VersionNumber
The version of GMSH of the msh file, equals usually 2.2.
int DoubleSize
how many bytes is a double?
std::vector< PhysicalEntity > PhysicalEntities
A list of all Physical entities that have a name.
std::vector< Element > Elements
A list of all Elements (Points,Lines,Surfaces or Volumes) present in the *.msh file.
ElementType
All possible element types (see GMSH documentation)
std::vector< std::pair< size_type, Eigen::Vector3d > > Nodes
The nodes that make up this mesh.
bool IsBinary
Is it a binary file?
std::vector< PeriodicEntity > Periodic
static const std::vector< ElementType > AllElementTypes
Contains a list of all element types that are possible.