Nektar++
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Attributes | List of all members
Nektar::Utilities::OutputGmsh Class Reference

Converter for Gmsh files. More...

#include <OutputGmsh.h>

Inheritance diagram for Nektar::Utilities::OutputGmsh:
[legend]

Public Member Functions

 OutputGmsh (NekMeshUtils::MeshSharedPtr m)
 
virtual ~OutputGmsh ()
 
virtual void Process ()
 Write mesh to output file. More...
 
- Public Member Functions inherited from Nektar::NekMeshUtils::OutputModule
NEKMESHUTILS_EXPORT OutputModule (MeshSharedPtr p_m)
 
NEKMESHUTILS_EXPORT void OpenStream ()
 Open a file for output. 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=std::string())
 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 std::shared_ptr< Modulecreate (NekMeshUtils::MeshSharedPtr m)
 Creates an instance of this class. More...
 

Static Public Attributes

static NekMeshUtils::ModuleKey className
 

Private Attributes

std::unordered_map< NekMeshUtils::ElmtConfig, unsigned int, ElmtConfigHashelmMap
 

Additional Inherited Members

- 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::OutputModule
io::filtering_ostream m_mshFile
 Output stream. More...
 
std::ofstream m_mshFileStream
 Input stream. More...
 
- Protected Attributes inherited from Nektar::NekMeshUtils::Module
MeshSharedPtr m_mesh
 Mesh object. More...
 
std::map< std::string, ConfigOptionm_config
 List of configuration values. More...
 

Detailed Description

Converter for Gmsh files.

Definition at line 66 of file OutputGmsh.h.

Constructor & Destructor Documentation

◆ OutputGmsh()

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

Definition at line 55 of file OutputGmsh.cpp.

References elmMap, Nektar::Utilities::InputGmsh::GenElmMap(), and Nektar::NekMeshUtils::Module::m_config.

55  : OutputModule(m)
56 {
57  // Populate #InputGmsh::elmMap and use this to construct an
58  // inverse mapping from %ElmtConfig to Gmsh ID.
59  for (auto &it : InputGmsh::GenElmMap())
60  {
61  elmMap[it.second] = it.first;
62  }
63 
64  m_config["order"] = ConfigOption(false, "-1", "Enforce a polynomial order");
65 }
std::unordered_map< NekMeshUtils::ElmtConfig, unsigned int, ElmtConfigHash > elmMap
Definition: OutputGmsh.h:82
Represents a command-line configuration option.
std::map< std::string, ConfigOption > m_config
List of configuration values.
NEKMESHUTILS_EXPORT OutputModule(MeshSharedPtr p_m)
static std::map< unsigned int, NekMeshUtils::ElmtConfig > GenElmMap()
Definition: InputGmsh.cpp:1890

◆ ~OutputGmsh()

Nektar::Utilities::OutputGmsh::~OutputGmsh ( )
virtual

Definition at line 67 of file OutputGmsh.cpp.

68 {
69 }

Member Function Documentation

◆ create()

static std::shared_ptr<Module> Nektar::Utilities::OutputGmsh::create ( NekMeshUtils::MeshSharedPtr  m)
inlinestatic

Creates an instance of this class.

Definition at line 70 of file OutputGmsh.h.

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

70  {
72  }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.

◆ Process()

void Nektar::Utilities::OutputGmsh::Process ( )
virtual

Write mesh to output file.

Process a mesh to output to Gmsh MSH format.

Gmsh output is fairly straightforward. The file first contains a list of nodes, followed by a list of elements. Since Mesh::vertexSet only contains vertices of the linear elements, we first loop over the elements so that any high-order vertices can be enumerated and then added to the node list. We then print out the list of nodes and finally print the element list.

Implements Nektar::NekMeshUtils::Module.

Definition at line 81 of file OutputGmsh.cpp.

References Nektar::NekMeshUtils::HOTriangle< T >::Align(), Nektar::NekMeshUtils::HOQuadrilateral< T >::Align(), ASSERTL1, Nektar::Utilities::InputGmsh::CreateReordering(), Nektar::StdRegions::eForwards, elmMap, Nektar::LibUtilities::ePolyEvenlySpaced, Nektar::NekMeshUtils::Module::m_config, Nektar::NekMeshUtils::Module::m_mesh, Nektar::NekMeshUtils::OutputModule::m_mshFile, Nektar::NekMeshUtils::OutputModule::OpenStream(), Nektar::NekMeshUtils::HOTriangle< T >::surfVerts, and Nektar::NekMeshUtils::HOQuadrilateral< T >::surfVerts.

82 {
83  if (m_mesh->m_verbose)
84  {
85  cout << "OutputGmsh: Writing file..." << endl;
86  }
87 
88  std::unordered_map<int, vector<int> > orderingMap;
89 
90  // Open the file stream.
91  OpenStream();
92 
93  // Write MSH header
94  m_mshFile << "$MeshFormat" << endl
95  << "2.2 0 8" << endl
96  << "$EndMeshFormat" << endl;
97 
98  int id = m_mesh->m_vertexSet.size();
99  vector<ElementSharedPtr> toComplete;
100 
101  int order = m_config["order"].as<int>();
102 
103  if (order != -1)
104  {
105  if (m_mesh->m_verbose)
106  {
107  cout << "Making mesh of order " << order << endl;
108  }
109  }
110  else
111  {
112  // Do first pass over elements of expansion dimension to determine
113  // which elements need completion.
114  for (int i = 0; i < m_mesh->m_element[m_mesh->m_expDim].size(); ++i)
115  {
116  ElementSharedPtr e = m_mesh->m_element[m_mesh->m_expDim][i];
117  if (e->GetMaxOrder() > order)
118  {
119  order = e->GetMaxOrder();
120  }
121  }
122  }
123 
124  // Convert this mesh into a high-order mesh of uniform order.
125  if (m_mesh->m_verbose)
126  {
127  cout << "Mesh order of " << order << " detected" << endl;
128  }
129 
130  m_mesh->MakeOrder(order, LibUtilities::ePolyEvenlySpaced);
131 
132  // Add edge- and face-interior nodes to vertex set.
133  for (auto &eIt : m_mesh->m_edgeSet)
134  {
135  m_mesh->m_vertexSet.insert(eIt->m_edgeNodes.begin(),
136  eIt->m_edgeNodes.end());
137  }
138 
139  for (auto &fIt : m_mesh->m_faceSet)
140  {
141  m_mesh->m_vertexSet.insert(fIt->m_faceNodes.begin(),
142  fIt->m_faceNodes.end());
143  }
144 
145  // Do second pass over elements for volume nodes.
146  for (int d = 1; d <= 3; ++d)
147  {
148  for (int i = 0; i < m_mesh->m_element[d].size(); ++i)
149  {
150  ElementSharedPtr e = m_mesh->m_element[d][i];
151  vector<NodeSharedPtr> volList = e->GetVolumeNodes();
152  m_mesh->m_vertexSet.insert(volList.begin(), volList.end());
153  }
154  }
155 
156  // Create ordered set of nodes - not required but looks nicer.
157  map<int, NodeSharedPtr> tmp;
158  for (const auto &it : m_mesh->m_vertexSet)
159  {
160  tmp[it->GetID() + 1] = it;
161  }
162 
163  // Write out nodes section.
164  m_mshFile << "$Nodes" << endl << m_mesh->m_vertexSet.size() << endl;
165 
166  for (auto &it : tmp)
167  {
168  m_mshFile << it.first << " " << scientific << setprecision(10)
169  << it.second->m_x << " " << it.second->m_y << " "
170  << it.second->m_z << endl;
171  }
172 
173  m_mshFile << "$EndNodes" << endl;
174 
175  // Write elements section. All other sections are not currently
176  // supported (physical names etc).
177  m_mshFile << "$Elements" << endl;
178  m_mshFile << m_mesh->GetNumEntities() << endl;
179 
180  id = 1;
181 
182  for (int d = 1; d <= 3; ++d)
183  {
184  for (int i = 0; i < m_mesh->m_element[d].size(); ++i, ++id)
185  {
186  ElementSharedPtr e = m_mesh->m_element[d][i];
187 
188  // First output element ID and type.
189  int elmtType = elmMap[e->GetConf()];
190  m_mshFile << id << " " << elmtType << " ";
191 
192  // Write out number of element tags and then the tags
193  // themselves.
194  vector<int> tags = e->GetTagList();
195 
196  if (tags.size() == 1)
197  {
198  tags.push_back(tags[0]);
199  tags.push_back(0);
200  }
201 
202  m_mshFile << tags.size() << " ";
203 
204  for (int j = 0; j < tags.size(); ++j)
205  {
206  m_mshFile << tags[j] << " ";
207  }
208 
209  // Finally write out node list. First write vertices, then
210  // internal edge nodes, then face nodes.
211  vector<NodeSharedPtr> nodeList = e->GetVertexList();
212  vector<EdgeSharedPtr> edgeList = e->GetEdgeList();
213  vector<FaceSharedPtr> faceList = e->GetFaceList();
214  vector<NodeSharedPtr> volList = e->GetVolumeNodes();
215 
216  tags.clear();
217 
218  for (int j = 0; j < nodeList.size(); ++j)
219  {
220  tags.push_back(nodeList[j]->m_id);
221  }
222 
223  // Process edge-interior points
224  for (int j = 0; j < edgeList.size(); ++j)
225  {
226  nodeList = edgeList[j]->m_edgeNodes;
227 
228  if (e->GetEdgeOrient(j, edgeList[j]) == StdRegions::eForwards)
229  {
230  for (int k = 0; k < nodeList.size(); ++k)
231  {
232  tags.push_back(nodeList[k]->m_id);
233  }
234  }
235  else
236  {
237  for (int k = nodeList.size() - 1; k >= 0; --k)
238  {
239  tags.push_back(nodeList[k]->m_id);
240  }
241  }
242  }
243 
244  // Process face-interior points
245  for (int j = 0; j < faceList.size(); ++j)
246  {
247  nodeList = faceList[j]->m_faceNodes;
248  int nFaceVerts = faceList[j]->m_vertexList.size();
249  vector<int> faceIds(nFaceVerts), volFaceIds(nFaceVerts);
250 
251  for (int k = 0; k < nFaceVerts; ++k)
252  {
253  faceIds [k] = faceList[j]->m_vertexList[k]->m_id;
254  volFaceIds[k] =
255  e->GetVertexList()[e->GetFaceVertex(j, k)]->m_id;
256  }
257 
258  if (nFaceVerts == 3)
259  {
260  HOTriangle<NodeSharedPtr> hoTri(faceIds, nodeList);
261  hoTri.Align(volFaceIds);
262  for (int k = 0; k < hoTri.surfVerts.size(); ++k)
263  {
264  tags.push_back(hoTri.surfVerts[k]->m_id);
265  }
266  }
267  else
268  {
269  HOQuadrilateral<NodeSharedPtr> hoQuad(faceIds, nodeList);
270  hoQuad.Align(volFaceIds);
271 
272  for (int k = 0; k < hoQuad.surfVerts.size(); ++k)
273  {
274  tags.push_back(hoQuad.surfVerts[k]->m_id);
275  }
276  }
277  }
278 
279  // Process volume nodes
280  for (int j = 0; j < volList.size(); ++j)
281  {
282  tags.push_back(volList[j]->m_id);
283  }
284 
285  // Construct inverse of input reordering. First try to find it in
286  // our cache.
287  auto oIt = orderingMap.find(elmtType);
288 
289  // If it's not created, then create it.
290  if (oIt == orderingMap.end())
291  {
292  vector<int> reordering = InputGmsh::CreateReordering(elmtType);
293  vector<int> inv(tags.size());
294 
295  ASSERTL1(tags.size() == reordering.size(),
296  "Reordering map size not equal to element tags 1.");
297 
298  for (int j = 0; j < tags.size(); ++j)
299  {
300  inv[reordering[j]] = j;
301  }
302 
303  oIt = orderingMap.insert(make_pair(elmtType, inv)).first;
304  }
305 
306  ASSERTL1(tags.size() == oIt->second.size(),
307  "Reordering map size not equal to element tags 2.");
308 
309  // Finally write element nodes.
310  for (int j = 0; j < tags.size(); ++j)
311  {
312  m_mshFile << tags[oIt->second[j]] + 1 << " ";
313  }
314 
315  m_mshFile << endl;
316  }
317  }
318  m_mshFile << "$EndElements" << endl;
319 }
io::filtering_ostream m_mshFile
Output stream.
NEKMESHUTILS_EXPORT void OpenStream()
Open a file for output.
1D Evenly-spaced points using Lagrange polynomial
Definition: PointsType.h:64
std::unordered_map< NekMeshUtils::ElmtConfig, unsigned int, ElmtConfigHash > elmMap
Definition: OutputGmsh.h:82
static std::vector< int > CreateReordering(unsigned int InputGmshEntity)
Create a reordering map for a given element.
Definition: InputGmsh.cpp:1218
std::shared_ptr< Element > ElementSharedPtr
Definition: Edge.h:49
std::map< std::string, ConfigOption > m_config
List of configuration values.
A lightweight struct for dealing with high-order triangle alignment.
Definition: HOAlignment.h:49
A lightweight struct for dealing with high-order quadrilateral alignment.
Definition: HOAlignment.h:208
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250

Member Data Documentation

◆ className

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

Definition at line 73 of file OutputGmsh.h.

◆ elmMap

std::unordered_map<NekMeshUtils::ElmtConfig, unsigned int, ElmtConfigHash> Nektar::Utilities::OutputGmsh::elmMap
private

Definition at line 82 of file OutputGmsh.h.

Referenced by OutputGmsh(), and Process().