Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions | Static Private Member Functions | List of all members
Nektar::Utilities::InputGmsh Class Reference

#include <InputGmsh.h>

Inheritance diagram for Nektar::Utilities::InputGmsh:
Inheritance graph
[legend]
Collaboration diagram for Nektar::Utilities::InputGmsh:
Collaboration graph
[legend]

Public Member Functions

 InputGmsh (NekMeshUtils::MeshSharedPtr m)
 Set up InputGmsh object. More...
 
virtual ~InputGmsh ()
 
virtual void Process ()
 
- Public Member Functions inherited from Nektar::NekMeshUtils::InputModule
NEKMESHUTILS_EXPORT InputModule (MeshSharedPtr p_m)
 
NEKMESHUTILS_EXPORT void OpenStream ()
 Open a file for input. More...
 
- Public Member Functions inherited from Nektar::NekMeshUtils::Module
NEKMESHUTILS_EXPORT Module (MeshSharedPtr p_m)
 
NEKMESHUTILS_EXPORT void RegisterConfig (std::string key, std::string value)
 Register a configuration option with a module. More...
 
NEKMESHUTILS_EXPORT void PrintConfig ()
 Print out all configuration options for a module. More...
 
NEKMESHUTILS_EXPORT void SetDefaults ()
 Sets default configuration options for those which have not been set. More...
 
NEKMESHUTILS_EXPORT MeshSharedPtr GetMesh ()
 
virtual NEKMESHUTILS_EXPORT void ProcessVertices ()
 Extract element vertices. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessEdges (bool ReprocessEdges=true)
 Extract element edges. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessFaces (bool ReprocessFaces=true)
 Extract element faces. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessElements ()
 Generate element IDs. More...
 
virtual NEKMESHUTILS_EXPORT void ProcessComposites ()
 Generate composites. More...
 
virtual NEKMESHUTILS_EXPORT void ClearElementLinks ()
 

Static Public Member Functions

static
NekMeshUtils::ModuleSharedPtr 
create (NekMeshUtils::MeshSharedPtr m)
 Creates an instance of this class. More...
 
static std::map< unsigned int,
NekMeshUtils::ElmtConfig
GenElmMap ()
 
static std::vector< int > CreateReordering (unsigned int InputGmshEntity)
 Create a reordering map for a given element. More...
 

Static Public Attributes

static NekMeshUtils::ModuleKey className
 ModuleKey for class. More...
 
static std::map< unsigned int,
NekMeshUtils::ElmtConfig
elmMap = InputGmsh::GenElmMap()
 

Private Member Functions

int GetNnodes (unsigned int InputGmshEntity)
 

Static Private Member Functions

static std::vector< int > TriReordering (NekMeshUtils::ElmtConfig conf)
 Create a reordering for triangles. More...
 
static std::vector< int > QuadReordering (NekMeshUtils::ElmtConfig conf)
 Create a reordering for quadrilaterals. More...
 
static std::vector< int > HexReordering (NekMeshUtils::ElmtConfig conf)
 Create a reordering for hexahedra. More...
 
static std::vector< int > PrismReordering (NekMeshUtils::ElmtConfig conf)
 Create a reordering for prisms. More...
 
static std::vector< int > TetReordering (NekMeshUtils::ElmtConfig conf)
 Create a reordering for tetrahedra. More...
 
static std::vector< int > LineReordering (NekMeshUtils::ElmtConfig conf)
 

Additional Inherited Members

- Protected Member Functions inherited from Nektar::NekMeshUtils::InputModule
NEKMESHUTILS_EXPORT void PrintSummary ()
 Print summary of elements. More...
 
- Protected Member Functions inherited from Nektar::NekMeshUtils::Module
NEKMESHUTILS_EXPORT void ReorderPrisms (PerMap &perFaces)
 Reorder node IDs so that prisms and tetrahedra are aligned correctly. More...
 
NEKMESHUTILS_EXPORT void PrismLines (int prism, PerMap &perFaces, std::set< int > &prismsDone, std::vector< ElementSharedPtr > &line)
 
- Protected Attributes inherited from Nektar::NekMeshUtils::InputModule
io::filtering_istream m_mshFile
 Input stream. More...
 
std::ifstream m_mshFileStream
 Input stream. More...
 
- Protected Attributes inherited from Nektar::NekMeshUtils::Module
MeshSharedPtr m_mesh
 Mesh object. More...
 
std::map< std::string,
ConfigOption
m_config
 List of configuration values. More...
 

Detailed Description

Converter for Gmsh files.

Definition at line 49 of file InputGmsh.h.

Constructor & Destructor Documentation

Nektar::Utilities::InputGmsh::InputGmsh ( NekMeshUtils::MeshSharedPtr  m)

Set up InputGmsh object.

Definition at line 701 of file InputGmsh.cpp.

701  : InputModule(m)
702 {
703 }
NEKMESHUTILS_EXPORT InputModule(MeshSharedPtr p_m)
Nektar::Utilities::InputGmsh::~InputGmsh ( )
virtual

Definition at line 705 of file InputGmsh.cpp.

706 {
707 }

Member Function Documentation

static NekMeshUtils::ModuleSharedPtr Nektar::Utilities::InputGmsh::create ( NekMeshUtils::MeshSharedPtr  m)
inlinestatic

Creates an instance of this class.

Definition at line 57 of file InputGmsh.h.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr().

58  {
60  }
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
vector< int > Nektar::Utilities::InputGmsh::CreateReordering ( unsigned int  InputGmshEntity)
static

Create a reordering map for a given element.

Since Gmsh and Nektar++ have different vertex, edge and face orientations, we need to reorder the nodes in a Gmsh MSH file so that they work with the Nektar++ orderings, since this is what is used in the elements defined in the converter.

Definition at line 1011 of file InputGmsh.cpp.

References Nektar::LibUtilities::eHexahedron, elmMap, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, HexReordering(), Nektar::iterator, LineReordering(), PrismReordering(), QuadReordering(), TetReordering(), and TriReordering().

Referenced by Process(), and Nektar::Utilities::OutputGmsh::Process().

1012 {
1014 
1015  it = elmMap.find(InputGmshEntity);
1016 
1017  if (it == elmMap.end())
1018  {
1019  cerr << "Unknown element type " << InputGmshEntity << endl;
1020  abort();
1021  }
1022 
1023  // For specific elements, call the appropriate function to perform
1024  // the renumbering.
1025  switch (it->second.m_e)
1026  {
1028  return TriReordering(it->second);
1029  break;
1031  return QuadReordering(it->second);
1032  break;
1034  return TetReordering(it->second);
1035  break;
1036  case LibUtilities::ePrism:
1037  return PrismReordering(it->second);
1038  break;
1040  return HexReordering(it->second);
1041  break;
1043  return LineReordering(it->second);
1044  default:
1045  break;
1046  }
1047 
1048  // Default: no reordering.
1049  vector<int> returnVal;
1050  return returnVal;
1051 }
static std::vector< int > PrismReordering(NekMeshUtils::ElmtConfig conf)
Create a reordering for prisms.
Definition: InputGmsh.cpp:1318
static std::vector< int > TetReordering(NekMeshUtils::ElmtConfig conf)
Create a reordering for tetrahedra.
Definition: InputGmsh.cpp:1166
static std::vector< int > HexReordering(NekMeshUtils::ElmtConfig conf)
Create a reordering for hexahedra.
Definition: InputGmsh.cpp:1537
static std::vector< int > LineReordering(NekMeshUtils::ElmtConfig conf)
Definition: InputGmsh.cpp:1053
static std::vector< int > QuadReordering(NekMeshUtils::ElmtConfig conf)
Create a reordering for quadrilaterals.
Definition: InputGmsh.cpp:1118
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
static std::vector< int > TriReordering(NekMeshUtils::ElmtConfig conf)
Create a reordering for triangles.
Definition: InputGmsh.cpp:1069
static std::map< unsigned int, NekMeshUtils::ElmtConfig > elmMap
Definition: InputGmsh.h:68
std::map< unsigned int, ElmtConfig > Nektar::Utilities::InputGmsh::GenElmMap ( )
static

Definition at line 1685 of file InputGmsh.cpp.

References Nektar::LibUtilities::eHexahedron, Nektar::LibUtilities::ePoint, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, and Nektar::LibUtilities::eTriangle.

Referenced by Nektar::Utilities::OutputGmsh::OutputGmsh().

1686 {
1687  using namespace LibUtilities;
1688  std::map<unsigned int, ElmtConfig> tmp;
1689 
1690  // Elmt type, order, face, volume
1691  tmp[ 1] = ElmtConfig(eSegment, 1, false, false);
1692  tmp[ 2] = ElmtConfig(eTriangle, 1, false, false);
1693  tmp[ 3] = ElmtConfig(eQuadrilateral, 1, false, false);
1694  tmp[ 4] = ElmtConfig(eTetrahedron, 1, false, false);
1695  tmp[ 5] = ElmtConfig(eHexahedron, 1, false, false);
1696  tmp[ 6] = ElmtConfig(ePrism, 1, false, false);
1697  tmp[ 7] = ElmtConfig(ePyramid, 1, false, false);
1698  tmp[ 8] = ElmtConfig(eSegment, 2, true, false);
1699  tmp[ 9] = ElmtConfig(eTriangle, 2, false, false);
1700  tmp[ 10] = ElmtConfig(eQuadrilateral, 2, true, false);
1701  tmp[ 11] = ElmtConfig(eTetrahedron, 2, false, false);
1702  tmp[ 12] = ElmtConfig(eHexahedron, 2, true, true);
1703  tmp[ 13] = ElmtConfig(ePrism, 2, true, false);
1704  tmp[ 14] = ElmtConfig(ePyramid, 2, true, false);
1705  tmp[ 15] = ElmtConfig(ePoint, 1, false, false);
1706  tmp[ 16] = ElmtConfig(eQuadrilateral, 2, false, false);
1707  tmp[ 17] = ElmtConfig(eHexahedron, 2, false, false);
1708  tmp[ 18] = ElmtConfig(ePrism, 2, false, false);
1709  tmp[ 19] = ElmtConfig(ePyramid, 2, false, false);
1710  tmp[ 20] = ElmtConfig(eTriangle, 3, false, false);
1711  tmp[ 21] = ElmtConfig(eTriangle, 3, true, false);
1712  tmp[ 22] = ElmtConfig(eTriangle, 4, false, false);
1713  tmp[ 23] = ElmtConfig(eTriangle, 4, true, false);
1714  tmp[ 24] = ElmtConfig(eTriangle, 5, false, false);
1715  tmp[ 25] = ElmtConfig(eTriangle, 5, true, false);
1716  tmp[ 26] = ElmtConfig(eSegment, 3, true, false);
1717  tmp[ 27] = ElmtConfig(eSegment, 4, true, false);
1718  tmp[ 28] = ElmtConfig(eSegment, 5, true, false);
1719  tmp[ 29] = ElmtConfig(eTetrahedron, 3, true, false);
1720  tmp[ 30] = ElmtConfig(eTetrahedron, 4, true, true);
1721  tmp[ 31] = ElmtConfig(eTetrahedron, 5, true, true);
1722  tmp[ 32] = ElmtConfig(eTetrahedron, 4, true, false);
1723  tmp[ 33] = ElmtConfig(eTetrahedron, 5, true, false);
1724  tmp[ 36] = ElmtConfig(eQuadrilateral, 3, true, false);
1725  tmp[ 37] = ElmtConfig(eQuadrilateral, 4, true, false);
1726  tmp[ 38] = ElmtConfig(eQuadrilateral, 5, true, false);
1727  tmp[ 39] = ElmtConfig(eQuadrilateral, 3, false, false);
1728  tmp[ 40] = ElmtConfig(eQuadrilateral, 4, false, false);
1729  tmp[ 41] = ElmtConfig(eQuadrilateral, 5, false, false);
1730  tmp[ 42] = ElmtConfig(eTriangle, 6, true, false);
1731  tmp[ 43] = ElmtConfig(eTriangle, 7, true, false);
1732  tmp[ 44] = ElmtConfig(eTriangle, 8, true, false);
1733  tmp[ 45] = ElmtConfig(eTriangle, 9, true, false);
1734  tmp[ 46] = ElmtConfig(eTriangle, 10, true, false);
1735  tmp[ 47] = ElmtConfig(eQuadrilateral, 6, true, false);
1736  tmp[ 48] = ElmtConfig(eQuadrilateral, 7, true, false);
1737  tmp[ 49] = ElmtConfig(eQuadrilateral, 8, true, false);
1738  tmp[ 50] = ElmtConfig(eQuadrilateral, 9, true, false);
1739  tmp[ 51] = ElmtConfig(eQuadrilateral, 10, true, false);
1740  tmp[ 52] = ElmtConfig(eTriangle, 6, false, false);
1741  tmp[ 53] = ElmtConfig(eTriangle, 7, false, false);
1742  tmp[ 54] = ElmtConfig(eTriangle, 8, false, false);
1743  tmp[ 55] = ElmtConfig(eTriangle, 9, false, false);
1744  tmp[ 56] = ElmtConfig(eTriangle, 10, false, false);
1745  tmp[ 57] = ElmtConfig(eQuadrilateral, 6, false, false);
1746  tmp[ 58] = ElmtConfig(eQuadrilateral, 7, false, false);
1747  tmp[ 59] = ElmtConfig(eQuadrilateral, 8, false, false);
1748  tmp[ 60] = ElmtConfig(eQuadrilateral, 9, false, false);
1749  tmp[ 61] = ElmtConfig(eQuadrilateral, 10, false, false);
1750  tmp[ 62] = ElmtConfig(eSegment, 6, true, false);
1751  tmp[ 63] = ElmtConfig(eSegment, 7, true, false);
1752  tmp[ 64] = ElmtConfig(eSegment, 8, true, false);
1753  tmp[ 65] = ElmtConfig(eSegment, 9, true, false);
1754  tmp[ 66] = ElmtConfig(eSegment, 10, true, false);
1755  tmp[ 71] = ElmtConfig(eTetrahedron, 6, true, true);
1756  tmp[ 72] = ElmtConfig(eTetrahedron, 7, true, true);
1757  tmp[ 73] = ElmtConfig(eTetrahedron, 8, true, true);
1758  tmp[ 74] = ElmtConfig(eTetrahedron, 9, true, true);
1759  tmp[ 75] = ElmtConfig(eTetrahedron, 10, true, true);
1760  tmp[ 79] = ElmtConfig(eTetrahedron, 6, true, false);
1761  tmp[ 80] = ElmtConfig(eTetrahedron, 7, true, false);
1762  tmp[ 81] = ElmtConfig(eTetrahedron, 8, true, false);
1763  tmp[ 82] = ElmtConfig(eTetrahedron, 9, true, false);
1764  tmp[ 83] = ElmtConfig(eTetrahedron, 10, true, false);
1765  tmp[ 90] = ElmtConfig(ePrism, 3, true, true);
1766  tmp[ 91] = ElmtConfig(ePrism, 4, true, true);
1767  tmp[ 92] = ElmtConfig(eHexahedron, 3, true, true);
1768  tmp[ 93] = ElmtConfig(eHexahedron, 4, true, true);
1769  tmp[ 94] = ElmtConfig(eHexahedron, 5, true, true);
1770  tmp[ 95] = ElmtConfig(eHexahedron, 6, true, true);
1771  tmp[ 96] = ElmtConfig(eHexahedron, 7, true, true);
1772  tmp[ 97] = ElmtConfig(eHexahedron, 8, true, true);
1773  tmp[ 98] = ElmtConfig(eHexahedron, 9, true, true);
1774  tmp[ 99] = ElmtConfig(eHexahedron, 3, true, false);
1775  tmp[100] = ElmtConfig(eHexahedron, 4, true, false);
1776  tmp[101] = ElmtConfig(eHexahedron, 5, true, false);
1777  tmp[102] = ElmtConfig(eHexahedron, 6, true, false);
1778  tmp[103] = ElmtConfig(eHexahedron, 7, true, false);
1779  tmp[104] = ElmtConfig(eHexahedron, 8, true, false);
1780  tmp[105] = ElmtConfig(eHexahedron, 9, true, false);
1781  tmp[106] = ElmtConfig(ePrism, 5, true, true);
1782  tmp[107] = ElmtConfig(ePrism, 6, true, true);
1783  tmp[108] = ElmtConfig(ePrism, 7, true, true);
1784  tmp[109] = ElmtConfig(ePrism, 8, true, true);
1785  tmp[110] = ElmtConfig(ePrism, 9, true, true);
1786  tmp[111] = ElmtConfig(ePrism, 3, true, false);
1787  tmp[112] = ElmtConfig(ePrism, 4, true, false);
1788  tmp[113] = ElmtConfig(ePrism, 5, true, false);
1789  tmp[114] = ElmtConfig(ePrism, 6, true, false);
1790  tmp[115] = ElmtConfig(ePrism, 7, true, false);
1791  tmp[116] = ElmtConfig(ePrism, 8, true, false);
1792  tmp[117] = ElmtConfig(ePrism, 9, true, false);
1793  tmp[118] = ElmtConfig(ePyramid, 3, true, true);
1794  tmp[119] = ElmtConfig(ePyramid, 4, true, true);
1795  tmp[120] = ElmtConfig(ePyramid, 5, true, true);
1796  tmp[121] = ElmtConfig(ePyramid, 6, true, true);
1797  tmp[122] = ElmtConfig(ePyramid, 7, true, true);
1798  tmp[123] = ElmtConfig(ePyramid, 8, true, true);
1799  tmp[124] = ElmtConfig(ePyramid, 9, true, true);
1800  tmp[125] = ElmtConfig(ePyramid, 3, true, false);
1801  tmp[126] = ElmtConfig(ePyramid, 4, true, false);
1802  tmp[127] = ElmtConfig(ePyramid, 5, true, false);
1803  tmp[128] = ElmtConfig(ePyramid, 6, true, false);
1804  tmp[129] = ElmtConfig(ePyramid, 7, true, false);
1805  tmp[130] = ElmtConfig(ePyramid, 7, true, false);
1806  tmp[131] = ElmtConfig(ePyramid, 8, true, false);
1807 
1808  return tmp;
1809 }
Basic information about an element.
Definition: ElementConfig.h:50
int Nektar::Utilities::InputGmsh::GetNnodes ( unsigned int  InputGmshEntity)
private

For a given msh ID, return the corresponding number of nodes.

Definition at line 954 of file InputGmsh.cpp.

References Nektar::LibUtilities::eHexahedron, elmMap, Nektar::LibUtilities::eNodalTriEvenlySpaced, Nektar::LibUtilities::ePoint, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::NekMeshUtils::Point::GetNumNodes(), Nektar::NekMeshUtils::Pyramid::GetNumNodes(), Nektar::NekMeshUtils::Line::GetNumNodes(), Nektar::NekMeshUtils::Quadrilateral::GetNumNodes(), Nektar::NekMeshUtils::Prism::GetNumNodes(), Nektar::NekMeshUtils::Tetrahedron::GetNumNodes(), Nektar::NekMeshUtils::Triangle::GetNumNodes(), Nektar::NekMeshUtils::Hexahedron::GetNumNodes(), and Nektar::iterator.

Referenced by Process().

955 {
956  int nNodes;
958 
959  it = elmMap.find(InputGmshEntity);
960 
961  if (it == elmMap.end())
962  {
963  cerr << "Unknown element type " << InputGmshEntity << endl;
964  abort();
965  }
966 
967  switch (it->second.m_e)
968  {
970  nNodes = Point::GetNumNodes(it->second);
971  break;
973  nNodes = Line::GetNumNodes(it->second);
974  break;
976  nNodes = Triangle::GetNumNodes(it->second);
977  break;
979  nNodes = Quadrilateral::GetNumNodes(it->second);
980  break;
982  nNodes = Tetrahedron::GetNumNodes(it->second);
983  it->second.m_faceCurveType = LibUtilities::eNodalTriEvenlySpaced;
984  break;
986  nNodes = Pyramid::GetNumNodes(it->second);
987  break;
989  nNodes = Prism::GetNumNodes(it->second);
990  break;
992  nNodes = Hexahedron::GetNumNodes(it->second);
993  break;
994  default:
995  cerr << "Unknown element type!" << endl;
996  abort();
997  break;
998  }
999 
1000  return nNodes;
1001 }
static NEKMESHUTILS_EXPORT unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a quadrilateral.
static NEKMESHUTILS_EXPORT unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a line.
Definition: Line.cpp:187
static NEKMESHUTILS_EXPORT unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a prism.
Definition: Prism.cpp:234
static NEKMESHUTILS_EXPORT unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a triangle.
static NEKMESHUTILS_EXPORT unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a hexahedron.
Definition: Hexahedron.cpp:271
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
static NEKMESHUTILS_EXPORT unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a tetrahedron.
static NEKMESHUTILS_EXPORT unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a pyramid.
Definition: Pyramid.cpp:175
static NEKMESHUTILS_EXPORT unsigned int GetNumNodes(ElmtConfig pConf)
Return the number of nodes defining a point (i.e. return 1).
Definition: Point.cpp:66
2D Evenly-spaced points on a Triangle
Definition: PointsType.h:72
static std::map< unsigned int, NekMeshUtils::ElmtConfig > elmMap
Definition: InputGmsh.h:68
vector< int > Nektar::Utilities::InputGmsh::HexReordering ( NekMeshUtils::ElmtConfig  conf)
staticprivate

Create a reordering for hexahedra.

Definition at line 1537 of file InputGmsh.cpp.

References Nektar::StdRegions::eDir1BwdDir1_Dir2FwdDir2, Nektar::StdRegions::eDir1FwdDir1_Dir2FwdDir2, Nektar::StdRegions::eDir1FwdDir2_Dir2FwdDir1, Nektar::Utilities::hexTensorNodeOrdering(), Nektar::NekMeshUtils::ElmtConfig::m_faceNodes, Nektar::NekMeshUtils::ElmtConfig::m_order, Nektar::NekMeshUtils::ElmtConfig::m_volumeNodes, and Nektar::Utilities::quadTensorNodeOrdering().

Referenced by CreateReordering().

1538 {
1539  const int order = conf.m_order;
1540  const int n = order - 1;
1541  const int n2 = n * n;
1542  int i, j, k;
1543 
1544  vector<int> mapping;
1545 
1546  // Map taking Gmsh edges to Nektar++ edges.
1547  static int gmshToNekEdge[12] = {0, -3, 4, 1, 5, 2, 6, 7, 8, -11, 9, 10};
1548 
1549  // Push back vertices.
1550  mapping.resize(8);
1551  for (i = 0; i < 8; ++i)
1552  {
1553  mapping[i] = i;
1554  }
1555 
1556  if (order == 1)
1557  {
1558  return mapping;
1559  }
1560 
1561  // Curvilinear edges
1562  mapping.resize(8 + 12 * n);
1563 
1564  // Reorder edges.
1565  int cnt = 8, offset;
1566  for (i = 0; i < 12; ++i)
1567  {
1568  int edge = gmshToNekEdge[i];
1569  offset = 8 + n * abs(edge);
1570 
1571  if (edge < 0)
1572  {
1573  for (int j = 0; j < n; ++j)
1574  {
1575  mapping[offset + n - j - 1] = cnt++;
1576  }
1577  }
1578  else
1579  {
1580  for (int j = 0; j < n; ++j)
1581  {
1582  mapping[offset + j] = cnt++;
1583  }
1584  }
1585  }
1586 
1587  if (conf.m_faceNodes == false || n2 == 0)
1588  {
1589  return mapping;
1590  }
1591 
1592  // Curvilinear face nodes.
1593  mapping.resize(8 + 12 * n + 6 * n2);
1594 
1595  // Map which takes Gmsh -> Nektar++ faces in the local element.
1596  static int gmsh2NekFace[6] = {0, 1, 4, 2, 3, 5};
1597 
1598  // Map which defines orientation between Gmsh and Nektar++ faces.
1599  StdRegions::Orientation faceOrient[6] = {
1605  StdRegions::eDir1FwdDir1_Dir2FwdDir2};
1606 
1607  for (i = 0; i < 6; ++i)
1608  {
1609  int face = gmsh2NekFace[i];
1610  int offset2 = 8 + 12 * n + i * n2;
1611  offset = 8 + 12 * n + face * n2;
1612 
1613  // Create a list of interior face nodes for this face only.
1614  vector<int> faceNodes(n2);
1615  for (j = 0; j < n2; ++j)
1616  {
1617  faceNodes[j] = offset2 + j;
1618  }
1619 
1620  // Now get the reordering of this face, which puts Gmsh
1621  // recursive ordering into Nektar++ row-by-row order.
1622  vector<int> tmp = quadTensorNodeOrdering(faceNodes, n);
1623 
1624  // Finally reorient the face according to the geometry
1625  // differences.
1626  if (faceOrient[i] == StdRegions::eDir1FwdDir1_Dir2FwdDir2)
1627  {
1628  // Orientation is the same, just copy.
1629  for (j = 0; j < n2; ++j)
1630  {
1631  mapping[offset + j] = tmp[j];
1632  }
1633  }
1634  else if (faceOrient[i] == StdRegions::eDir1FwdDir2_Dir2FwdDir1)
1635  {
1636  // Tranposed faces
1637  for (j = 0; j < n; ++j)
1638  {
1639  for (k = 0; k < n; ++k)
1640  {
1641  mapping[offset + j * n + k] = tmp[k * n + j];
1642  }
1643  }
1644  }
1645  else if (faceOrient[i] == StdRegions::eDir1BwdDir1_Dir2FwdDir2)
1646  {
1647  for (j = 0; j < n; ++j)
1648  {
1649  for (k = 0; k < n; ++k)
1650  {
1651  mapping[offset + j * n + k] = tmp[j * n + (n - k - 1)];
1652  }
1653  }
1654  }
1655  }
1656 
1657  if (conf.m_volumeNodes == false)
1658  {
1659  return mapping;
1660  }
1661 
1662  const int totPoints = (order + 1) * (order + 1) * (order + 1);
1663  vector<int> interior;
1664  for (i = 8 + 12 * n + 6 * n2; i < totPoints; ++i)
1665  {
1666  interior.push_back(i);
1667  }
1668 
1669  interior = hexTensorNodeOrdering(interior, order - 1);
1670  mapping.insert(mapping.end(), interior.begin(), interior.end());
1671 
1672  return mapping;
1673 }
std::vector< int > quadTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a tensor product format suitable for the interior of a Nekt...
Definition: InputGmsh.cpp:93
std::vector< int > hexTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Ne...
Definition: InputGmsh.cpp:540
vector< int > Nektar::Utilities::InputGmsh::LineReordering ( NekMeshUtils::ElmtConfig  conf)
staticprivate

Definition at line 1053 of file InputGmsh.cpp.

References Nektar::NekMeshUtils::ElmtConfig::m_order.

Referenced by CreateReordering().

1054 {
1055  const int order = conf.m_order;
1056 
1057  vector<int> mapping(order+1);
1058  for(int i = 0; i < order+1; i++)
1059  {
1060  mapping[i] = i;
1061  }
1062 
1063  return mapping;
1064 }
vector< int > Nektar::Utilities::InputGmsh::PrismReordering ( NekMeshUtils::ElmtConfig  conf)
staticprivate

Create a reordering for prisms.

Note that whilst Gmsh MSH files have the capability to support high-order prisms, presently Gmsh does not seem to be capable of generating higher than second-order prismatic meshes, so most of the following is untested.

Definition at line 1318 of file InputGmsh.cpp.

References Nektar::NekMeshUtils::HOTriangle< T >::Align(), Nektar::NekMeshUtils::HOQuadrilateral< T >::Align(), Nektar::NekMeshUtils::ElmtConfig::m_faceNodes, Nektar::NekMeshUtils::ElmtConfig::m_order, Nektar::NekMeshUtils::ElmtConfig::m_volumeNodes, Nektar::Utilities::prismTensorNodeOrdering(), Nektar::Utilities::quadTensorNodeOrdering(), Nektar::NekMeshUtils::HOTriangle< T >::surfVerts, Nektar::NekMeshUtils::HOQuadrilateral< T >::surfVerts, and Nektar::Utilities::triTensorNodeOrdering().

Referenced by CreateReordering().

1319 {
1320  const int order = conf.m_order;
1321  const int n = order - 1;
1322 
1323  int i;
1324  vector<int> mapping(6);
1325 
1326  // To get from Gmsh -> Nektar++ prism, coordinates axes are
1327  // different; need to mirror in the triangular faces, and then
1328  // reorder vertices to make ordering anticlockwise on base quad.
1329  static int nekToGmshVerts[6] = {3, 4, 1, 0, 5, 2};
1330  // Inverse (gmsh vert -> Nektar++ vert): 3->0, 4->1, 1->2, 0->3, 5->4, 2->5
1331 
1332  for (i = 0; i < 6; ++i)
1333  {
1334  mapping[i] = nekToGmshVerts[i];
1335  }
1336 
1337  if (order == 1)
1338  {
1339  return mapping;
1340  }
1341 
1342  // Curvilinear edges.
1343  mapping.resize(6 + 9 * n);
1344 
1345  // Nektar++ edges:
1346  // 0 = 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 =
1347  // {0,1}, {1,2}, {3,2}, {0,3}, {0,4}, {1,4}, {2,5}, {3,5}, {4,5}
1348  // Gmsh edges (from Geo/MPrism.h of Gmsh source):
1349  // {0,1}, {0,2}, {0,3}, {1,2}, {1,4}, {2,5}, {3,4}, {3,5}, {4,5}
1350  // Apply inverse of gmshToNekVerts map:
1351  // {3,2}, {3,5}, {3,0}, {2,5}, {2,1}, {5,4}, {0,1}, {0,4}, {1,4}
1352  // Nektar++ mapping (negative indicates reverse orientation):
1353  // = 2 = 7 = -3 = 6 = -1 = -8 = 0 = 4 = 5
1354  static int gmshToNekEdge[9] = {2, 7, 3, 6, 1, 8, 0, 4, 5};
1355  static int gmshToNekRev[9] = {0, 0, 1, 0, 1, 1, 0, 0, 0};
1356 
1357  // Reorder edges.
1358  int offset, cnt = 6;
1359  for (i = 0; i < 9; ++i)
1360  {
1361  offset = 6 + n * gmshToNekEdge[i];
1362 
1363  if (gmshToNekRev[i])
1364  {
1365  for (int j = 0; j < n; ++j)
1366  {
1367  mapping[offset + n - j - 1] = cnt++;
1368  }
1369  }
1370  else
1371  {
1372  for (int j = 0; j < n; ++j)
1373  {
1374  mapping[offset + j] = cnt++;
1375  }
1376  }
1377  }
1378 
1379  if (conf.m_faceNodes == false)
1380  {
1381  return mapping;
1382  }
1383 
1384  int nTriInt = n * (n - 1) / 2;
1385  int nQuadInt = n * n;
1386 
1387  // Nektar++ faces:
1388  // 0 = {0,1,2,3}, 1 = {0,1,4}, 2 = {1,2,5,4}, 3 = {3,2,5}, 4 = {0,3,5,4}
1389  // Gmsh faces (from Geo/MPrism.h of Gmsh source):
1390  // {0,2,1}, {3,4,5}, {0,1,4,3}, {0,3,5,2}, {1,2,5,4}
1391  // Apply inverse of gmshToNekVerts map:
1392  // {3,5,2}, {0,1,4}, {3,2,1,0}, {3,0,4,5}, {2,5,4,1}
1393  // = 3 = 1 = 0 = 4 = 2
1394  // This gives gmsh -> Nektar++ faces:
1395  static int gmshToNekFace[5] = {3, 1, 0, 4, 2};
1396 
1397  // Face offsets
1398  vector<int> offsets(5), offsets2(5);
1399  offset = 6 + 9 * n;
1400 
1401  // Offsets in the gmsh order: face ordering is TTQQQ
1402  offsets[0] = offset;
1403  offsets[1] = offset + nTriInt;
1404  offsets[2] = offset + 2 * nTriInt;
1405  offsets[3] = offset + 2 * nTriInt + nQuadInt;
1406  offsets[4] = offset + 2 * nTriInt + 2 * nQuadInt;
1407 
1408  // Offsets in the Nektar++ order: face ordering is QTQTQ
1409  offsets2[0] = offset;
1410  offsets2[1] = offset + nQuadInt;
1411  offsets2[2] = offset + nQuadInt + nTriInt;
1412  offsets2[3] = offset + 2 * nQuadInt + nTriInt;
1413  offsets2[4] = offset + 2 * nQuadInt + 2 * nTriInt;
1414 
1415  mapping.resize(6 + 9 * n + 3 * nQuadInt + 2 * nTriInt);
1416 
1417  offset = 6 + 9 * n;
1418 
1419  vector<int> triVertId(3);
1420  triVertId[0] = 0;
1421  triVertId[1] = 1;
1422  triVertId[2] = 2;
1423 
1424  vector<int> quadVertId(4);
1425  quadVertId[0] = 0;
1426  quadVertId[1] = 1;
1427  quadVertId[2] = 2;
1428  quadVertId[3] = 3;
1429 
1430  for (i = 0; i < 5; ++i)
1431  {
1432  int face = gmshToNekFace[i];
1433  int offset2 = offsets[i];
1434  offset = offsets2[face];
1435 
1436  bool tri = i < 2;
1437  int nFacePts = tri ? nTriInt : nQuadInt;
1438 
1439  if (nFacePts == 0)
1440  {
1441  continue;
1442  }
1443 
1444  // Create a list of interior face nodes for this face only.
1445  vector<int> faceNodes(nFacePts);
1446  vector<int> toAlign(tri ? 3 : 4);
1447  for (int j = 0; j < nFacePts; ++j)
1448  {
1449  faceNodes[j] = offset2 + j;
1450  }
1451 
1452  if (tri)
1453  {
1454  // Now get the reordering of this face, which puts Gmsh
1455  // recursive ordering into Nektar++ row-by-row order.
1456  vector<int> tmp = triTensorNodeOrdering(faceNodes, n - 1);
1457  HOTriangle<int> hoTri(triVertId, tmp);
1458 
1459  // Apply reorientation
1460  if (i == 0)
1461  {
1462  // Triangle verts {0,2,1} --> {0,1,2}
1463  toAlign[0] = 0;
1464  toAlign[1] = 2;
1465  toAlign[2] = 1;
1466  hoTri.Align(toAlign);
1467  }
1468 
1469  // Fill in mapping.
1470  for (int j = 0; j < nTriInt; ++j)
1471  {
1472  mapping[offset + j] = hoTri.surfVerts[j];
1473  }
1474  }
1475  else
1476  {
1477  vector<int> tmp = quadTensorNodeOrdering(faceNodes, n);
1478  HOQuadrilateral<int> hoQuad(quadVertId, tmp);
1479 
1480  // Apply reorientation
1481  if (i == 2)
1482  {
1483  toAlign[0] = 3;
1484  toAlign[1] = 2;
1485  toAlign[2] = 1;
1486  toAlign[3] = 0;
1487  }
1488  else if (i == 3)
1489  {
1490  toAlign[0] = 1;
1491  toAlign[1] = 0;
1492  toAlign[2] = 3;
1493  toAlign[3] = 2;
1494  }
1495  else if (i == 4)
1496  {
1497  toAlign[0] = 3;
1498  toAlign[1] = 0;
1499  toAlign[2] = 1;
1500  toAlign[3] = 2;
1501  }
1502 
1503  hoQuad.Align(toAlign);
1504 
1505  // Fill in mapping.
1506  for (int j = 0; j < nQuadInt; ++j)
1507  {
1508  mapping[offset + j] = hoQuad.surfVerts[j];
1509  }
1510  }
1511  }
1512 
1513  if (conf.m_volumeNodes == false)
1514  {
1515  return mapping;
1516  }
1517 
1518  // Interior points
1519  offset = offsets[4] + nQuadInt;
1520  vector<int> intPoints, tmp;
1521 
1522  for (int i = offset; i < (order+1) * (order+1) * (order+2) / 2; ++i)
1523  {
1524  intPoints.push_back(i);
1525  }
1526 
1527  // Reorder interior points
1528  tmp = prismTensorNodeOrdering(intPoints, order - 1);
1529  mapping.insert(mapping.end(), tmp.begin(), tmp.end());
1530 
1531  return mapping;
1532 }
std::vector< int > prismTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Ne...
Definition: InputGmsh.cpp:464
std::vector< int > triTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Ne...
Definition: InputGmsh.cpp:170
std::vector< int > quadTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a tensor product format suitable for the interior of a Nekt...
Definition: InputGmsh.cpp:93
A lightweight struct for dealing with high-order triangle alignment.
Definition: HOAlignment.h:50
A lightweight struct for dealing with high-order quadrilateral alignment.
Definition: HOAlignment.h:215
void Nektar::Utilities::InputGmsh::Process ( )
virtual

Gmsh file contains a list of nodes and their coordinates, along with a list of elements and those nodes which define them. We read in and store the list of nodes in #m_node and store the list of elements in #m_element. Each new element is supplied with a list of entries from m_node which defines the element. Finally some mesh statistics are printed.

Parameters
pFilenameFilename of Gmsh file to read.

Implements Nektar::NekMeshUtils::Module.

Definition at line 718 of file InputGmsh.cpp.

References Nektar::LibUtilities::NekFactory< tKey, tBase, >::CreateInstance(), CreateReordering(), elmMap, Nektar::NekMeshUtils::GetElementFactory(), GetNnodes(), Nektar::iterator, Nektar::NekMeshUtils::Module::m_mesh, Nektar::NekMeshUtils::InputModule::m_mshFile, class_topology::Node, Nektar::NekMeshUtils::InputModule::OpenStream(), Nektar::NekMeshUtils::Module::ProcessComposites(), Nektar::NekMeshUtils::Module::ProcessEdges(), Nektar::NekMeshUtils::Module::ProcessElements(), Nektar::NekMeshUtils::Module::ProcessFaces(), Nektar::NekMeshUtils::Module::ProcessVertices(), and Nektar::LibUtilities::ShapeTypeMap.

719 {
720  // Open the file stream.
721  OpenStream();
722 
723  m_mesh->m_expDim = 0;
724  m_mesh->m_spaceDim = 0;
725  string line;
726  int nVertices = 0;
727  int nEntities = 0;
728  int elm_type = 0;
729  int prevId = -1;
730  int maxTagId = -1;
731 
733 
734  // This map takes each element ID and maps it to a permutation map
735  // that is required to take Gmsh element node orderings and map them
736  // to Nektar++ orderings.
737  boost::unordered_map<int, vector<int> > orderingMap;
738  boost::unordered_map<int, vector<int> >::iterator oIt;
739 
740  if (m_mesh->m_verbose)
741  {
742  cout << "InputGmsh: Start reading file..." << endl;
743  }
744 
745  while (!m_mshFile.eof())
746  {
747  getline(m_mshFile, line);
748  stringstream s(line);
749  string word;
750  s >> word;
751 
752  // Process nodes.
753  if (word == "$Nodes")
754  {
755  getline(m_mshFile, line);
756  stringstream s(line);
757  s >> nVertices;
758  int id = 0;
759  for (int i = 0; i < nVertices; ++i)
760  {
761  getline(m_mshFile, line);
762  stringstream st(line);
763  double x = 0, y = 0, z = 0;
764  st >> id >> x >> y >> z;
765 
766  if ((x * x) > 0.000001 && m_mesh->m_spaceDim < 1)
767  {
768  m_mesh->m_spaceDim = 1;
769  }
770  if ((y * y) > 0.000001 && m_mesh->m_spaceDim < 2)
771  {
772  m_mesh->m_spaceDim = 2;
773  }
774  if ((z * z) > 0.000001 && m_mesh->m_spaceDim < 3)
775  {
776  m_mesh->m_spaceDim = 3;
777  }
778 
779  id -= 1; // counter starts at 0
780 
781  if (id - prevId != 1)
782  {
783  cerr << "Gmsh vertex ids should be contiguous" << endl;
784  abort();
785  }
786  prevId = id;
787  m_mesh->m_node.push_back(
788  boost::shared_ptr<Node>(new Node(id, x, y, z)));
789  }
790  }
791  // Process elements
792  else if (word == "$Elements")
793  {
794  getline(m_mshFile, line);
795  stringstream s(line);
796  s >> nEntities;
797  for (int i = 0; i < nEntities; ++i)
798  {
799  getline(m_mshFile, line);
800  stringstream st(line);
801  int id = 0, num_tag = 0, num_nodes = 0;
802 
803  st >> id >> elm_type >> num_tag;
804  id -= 1; // counter starts at 0
805 
806  it = elmMap.find(elm_type);
807  if (it == elmMap.end())
808  {
809  cerr << "Error: element type " << elm_type
810  << " not supported" << endl;
811  abort();
812  }
813 
814  // Read element tags
815  vector<int> tags;
816  for (int j = 0; j < num_tag; ++j)
817  {
818  int tag = 0;
819  st >> tag;
820  tags.push_back(tag);
821  }
822  tags.resize(1);
823 
824  maxTagId = max(maxTagId, tags[0]);
825 
826  // Read element node list
827  vector<NodeSharedPtr> nodeList;
828  num_nodes = GetNnodes(elm_type);
829  for (int k = 0; k < num_nodes; ++k)
830  {
831  int node = 0;
832  st >> node;
833  node -= 1; // counter starts at 0
834  nodeList.push_back(m_mesh->m_node[node]);
835  }
836 
837  // Look up reordering.
838  oIt = orderingMap.find(elm_type);
839 
840  // If it's not created, then create it.
841  if (oIt == orderingMap.end())
842  {
843  oIt = orderingMap.insert(
844  make_pair(elm_type, CreateReordering(elm_type))).first;
845  }
846 
847  // Apply reordering map where necessary.
848  if (oIt->second.size() > 0)
849  {
850  vector<int> &mapping = oIt->second;
851  vector<NodeSharedPtr> tmp = nodeList;
852  for (int i = 0; i < mapping.size(); ++i)
853  {
854  nodeList[i] = tmp[mapping[i]];
855  }
856  }
857 
858  // Create element
860  it->second.m_e, it->second, nodeList, tags);
861 
862  // Determine mesh expansion dimension
863  if (E->GetDim() > m_mesh->m_expDim)
864  {
865  m_mesh->m_expDim = E->GetDim();
866  }
867  m_mesh->m_element[E->GetDim()].push_back(E);
868  }
869  }
870  }
871  m_mshFile.reset();
872 
873  // Go through element and remap tags if necessary.
874  map<int, map<LibUtilities::ShapeType, int> > compMap;
875  map<int, map<LibUtilities::ShapeType, int> >::iterator cIt;
877 
878  for (int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); ++i)
879  {
880  ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][i];
881  LibUtilities::ShapeType type = el->GetConf().m_e;
882 
883  vector<int> tags = el->GetTagList();
884  int tag = tags[0];
885 
886  cIt = compMap.find(tag);
887 
888  if (cIt == compMap.end())
889  {
890  compMap[tag][type] = tag;
891  continue;
892  }
893 
894  // Reset tag for this element.
895  sIt = cIt->second.find(type);
896  if (sIt == cIt->second.end())
897  {
898  maxTagId++;
899  cIt->second[type] = maxTagId;
900  tags[0] = maxTagId;
901  el->SetTagList(tags);
902  }
903  else if (sIt->second != tag)
904  {
905  tags[0] = sIt->second;
906  el->SetTagList(tags);
907  }
908  }
909 
910  bool printInfo = false;
911  for (cIt = compMap.begin(); cIt != compMap.end(); ++cIt)
912  {
913  if (cIt->second.size() > 1)
914  {
915  printInfo = true;
916  break;
917  }
918  }
919 
920  if (printInfo)
921  {
922  cout << "Multiple elements in composite detected; remapped:" << endl;
923  for (cIt = compMap.begin(); cIt != compMap.end(); ++cIt)
924  {
925  if (cIt->second.size() > 1)
926  {
927  sIt = cIt->second.begin();
928  cout << "- Tag " << cIt->first << " => " << sIt->second << " ("
929  << LibUtilities::ShapeTypeMap[sIt->first] << ")";
930  sIt++;
931 
932  for (; sIt != cIt->second.end(); ++sIt)
933  {
934  cout << ", " << sIt->second << " ("
935  << LibUtilities::ShapeTypeMap[sIt->first] << ")";
936  }
937 
938  cout << endl;
939  }
940  }
941  }
942 
943  // Process rest of mesh.
944  ProcessVertices();
945  ProcessEdges();
946  ProcessFaces();
947  ProcessElements();
949 }
io::filtering_istream m_mshFile
Input stream.
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:162
ElementFactory & GetElementFactory()
Definition: Element.cpp:47
const char *const ShapeTypeMap[]
Definition: ShapeType.hpp:66
NEKMESHUTILS_EXPORT void OpenStream()
Open a file for input.
static std::vector< int > CreateReordering(unsigned int InputGmshEntity)
Create a reordering map for a given element.
Definition: InputGmsh.cpp:1011
virtual NEKMESHUTILS_EXPORT void ProcessFaces(bool ReprocessFaces=true)
Extract element faces.
virtual NEKMESHUTILS_EXPORT void ProcessElements()
Generate element IDs.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
virtual NEKMESHUTILS_EXPORT void ProcessVertices()
Extract element vertices.
int GetNnodes(unsigned int InputGmshEntity)
Definition: InputGmsh.cpp:954
virtual NEKMESHUTILS_EXPORT void ProcessEdges(bool ReprocessEdges=true)
Extract element edges.
boost::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:49
virtual NEKMESHUTILS_EXPORT void ProcessComposites()
Generate composites.
static std::map< unsigned int, NekMeshUtils::ElmtConfig > elmMap
Definition: InputGmsh.h:68
vector< int > Nektar::Utilities::InputGmsh::QuadReordering ( NekMeshUtils::ElmtConfig  conf)
staticprivate

Create a reordering for quadrilaterals.

Definition at line 1118 of file InputGmsh.cpp.

References Nektar::NekMeshUtils::ElmtConfig::m_faceNodes, Nektar::NekMeshUtils::ElmtConfig::m_order, and Nektar::Utilities::quadTensorNodeOrdering().

Referenced by CreateReordering().

1119 {
1120  const int order = conf.m_order;
1121  const int n = order - 1;
1122 
1123  // Copy vertices.
1124  vector<int> mapping(4);
1125  for (int i = 0; i < 4; ++i)
1126  {
1127  mapping[i] = i;
1128  }
1129 
1130  if (order == 1)
1131  {
1132  return mapping;
1133  }
1134 
1135  // Curvilinear edges.
1136  mapping.resize(4 + 4 * n);
1137 
1138  for (int i = 4; i < 4 + 4 * n; ++i)
1139  {
1140  mapping[i] = i;
1141  }
1142 
1143  if (!conf.m_faceNodes)
1144  {
1145  return mapping;
1146  }
1147 
1148  // Interior nodes.
1149  vector<int> interior(n * n);
1150  for (int i = 0; i < interior.size(); ++i)
1151  {
1152  interior[i] = i + 4 + 4 * n;
1153  }
1154 
1155  if (interior.size() > 0)
1156  {
1157  interior = quadTensorNodeOrdering(interior, n);
1158  }
1159  mapping.insert(mapping.end(), interior.begin(), interior.end());
1160  return mapping;
1161 }
std::vector< int > quadTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a tensor product format suitable for the interior of a Nekt...
Definition: InputGmsh.cpp:93
vector< int > Nektar::Utilities::InputGmsh::TetReordering ( NekMeshUtils::ElmtConfig  conf)
staticprivate

Create a reordering for tetrahedra.

Definition at line 1166 of file InputGmsh.cpp.

References Nektar::NekMeshUtils::HOTriangle< T >::Align(), Nektar::NekMeshUtils::ElmtConfig::m_faceNodes, Nektar::NekMeshUtils::ElmtConfig::m_order, Nektar::NekMeshUtils::ElmtConfig::m_volumeNodes, Nektar::NekMeshUtils::HOTriangle< T >::surfVerts, Nektar::Utilities::tetTensorNodeOrdering(), and Nektar::Utilities::triTensorNodeOrdering().

Referenced by CreateReordering().

1167 {
1168  const int order = conf.m_order;
1169  const int n = order - 1;
1170  const int n2 = n * (n - 1) / 2;
1171 
1172  int i, j;
1173  vector<int> mapping(4);
1174 
1175  // Copy vertices.
1176  for (i = 0; i < 4; ++i)
1177  {
1178  mapping[i] = i;
1179  }
1180 
1181  if (order == 1)
1182  {
1183  return mapping;
1184  }
1185 
1186  // Curvilinear edges.
1187  mapping.resize(4 + 6 * n);
1188 
1189  // Curvilinear edges.
1190  static int gmshToNekEdge[6] = {0, 1, 2, 3, 5, 4};
1191  static int gmshToNekRev[6] = {0, 0, 1, 1, 1, 1};
1192 
1193  // Reorder edges.
1194  int offset, cnt = 4;
1195  for (i = 0; i < 6; ++i)
1196  {
1197  offset = 4 + n * gmshToNekEdge[i];
1198 
1199  if (gmshToNekRev[i])
1200  {
1201  for (int j = 0; j < n; ++j)
1202  {
1203  mapping[offset + n - j - 1] = cnt++;
1204  }
1205  }
1206  else
1207  {
1208  for (int j = 0; j < n; ++j)
1209  {
1210  mapping[offset + j] = cnt++;
1211  }
1212  }
1213  }
1214 
1215  if (conf.m_faceNodes == false || n2 == 0)
1216  {
1217  return mapping;
1218  }
1219 
1220  // Curvilinear faces.
1221  mapping.resize(4 + 6 * n + 4 * n2);
1222 
1223  static int gmshToNekFace[4] = {0, 1, 3, 2};
1224 
1225  vector<int> triVertId(3);
1226  triVertId[0] = 0;
1227  triVertId[1] = 1;
1228  triVertId[2] = 2;
1229 
1230  // Loop over Gmsh faces
1231  for (i = 0; i < 4; ++i)
1232  {
1233  int face = gmshToNekFace[i];
1234  int offset2 = 4 + 6 * n + i * n2;
1235  offset = 4 + 6 * n + face * n2;
1236 
1237  // Create a list of interior face nodes for this face only.
1238  vector<int> faceNodes(n2);
1239  vector<int> toAlign(3);
1240  for (j = 0; j < n2; ++j)
1241  {
1242  faceNodes[j] = offset2 + j;
1243  }
1244 
1245  // Now get the reordering of this face, which puts Gmsh
1246  // recursive ordering into Nektar++ row-by-row order.
1247  vector<int> tmp = triTensorNodeOrdering(faceNodes, n - 1);
1248  HOTriangle<int> hoTri(triVertId, tmp);
1249 
1250  // Apply reorientation
1251  if (i == 0 || i == 2)
1252  {
1253  // Triangle verts {0,2,1} --> {0,1,2}
1254  toAlign[0] = 0;
1255  toAlign[1] = 2;
1256  toAlign[2] = 1;
1257  hoTri.Align(toAlign);
1258  }
1259  else if (i == 3)
1260  {
1261  // Triangle verts {1,2,0} --> {0,1,2}
1262  toAlign[0] = 1;
1263  toAlign[1] = 2;
1264  toAlign[2] = 0;
1265  hoTri.Align(toAlign);
1266  }
1267 
1268  // Fill in mapping.
1269  for (j = 0; j < n2; ++j)
1270  {
1271  mapping[offset + j] = hoTri.surfVerts[j];
1272  }
1273  }
1274 
1275  if (conf.m_volumeNodes == false)
1276  {
1277  return mapping;
1278  }
1279 
1280  const int nInt = (order - 3) * (order - 2) * (order - 1) / 6;
1281  if (nInt <= 0)
1282  {
1283  return mapping;
1284  }
1285 
1286  if (nInt == 1)
1287  {
1288  mapping.push_back(mapping.size());
1289  return mapping;
1290  }
1291 
1292  int ntot = (order+1)*(order+2)*(order+3)/6;
1293  vector<int> interior;
1294 
1295  for (int i = 4 + 6 * n + 4 * n2; i < ntot; ++i)
1296  {
1297  interior.push_back(i);
1298  }
1299 
1300  if (interior.size() > 0)
1301  {
1302  interior = tetTensorNodeOrdering(interior, order-3);
1303  }
1304 
1305  mapping.insert(mapping.end(), interior.begin(), interior.end());
1306 
1307  return mapping;
1308 }
std::vector< int > triTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Ne...
Definition: InputGmsh.cpp:170
A lightweight struct for dealing with high-order triangle alignment.
Definition: HOAlignment.h:50
std::vector< int > tetTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Ne...
Definition: InputGmsh.cpp:285
vector< int > Nektar::Utilities::InputGmsh::TriReordering ( NekMeshUtils::ElmtConfig  conf)
staticprivate

Create a reordering for triangles.

Definition at line 1069 of file InputGmsh.cpp.

References Nektar::NekMeshUtils::ElmtConfig::m_faceNodes, Nektar::NekMeshUtils::ElmtConfig::m_order, and Nektar::Utilities::triTensorNodeOrdering().

Referenced by CreateReordering().

1070 {
1071  const int order = conf.m_order;
1072  const int n = order - 1;
1073 
1074  // Copy vertices.
1075  vector<int> mapping(3);
1076  for (int i = 0; i < 3; ++i)
1077  {
1078  mapping[i] = i;
1079  }
1080 
1081  if (order == 1)
1082  {
1083  return mapping;
1084  }
1085 
1086  // Curvilinear edges.
1087  mapping.resize(3 + 3 * n);
1088 
1089  for (int i = 3; i < 3 + 3 * n; ++i)
1090  {
1091  mapping[i] = i;
1092  }
1093 
1094  if (!conf.m_faceNodes)
1095  {
1096  return mapping;
1097  }
1098 
1099  // Interior nodes.
1100  vector<int> interior(n * (n - 1) / 2);
1101  for (int i = 0; i < interior.size(); ++i)
1102  {
1103  interior[i] = i + 3 + 3 * n;
1104  }
1105 
1106  if (interior.size() > 0)
1107  {
1108  interior = triTensorNodeOrdering(interior, n - 1);
1109  }
1110 
1111  mapping.insert(mapping.end(), interior.begin(), interior.end());
1112  return mapping;
1113 }
std::vector< int > triTensorNodeOrdering(const std::vector< int > &nodes, int n)
Reorder Gmsh nodes so that they appear in a "tensor product" format suitable for the interior of a Ne...
Definition: InputGmsh.cpp:170

Member Data Documentation

ModuleKey Nektar::Utilities::InputGmsh::className
static
Initial value:

ModuleKey for class.

Definition at line 62 of file InputGmsh.h.

std::map< unsigned int, ElmtConfig > Nektar::Utilities::InputGmsh::elmMap = InputGmsh::GenElmMap()
static

Element map; takes a msh id to an ElmtConfig object.

Definition at line 68 of file InputGmsh.h.

Referenced by CreateReordering(), GetNnodes(), and Process().