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 Attributes | List of all members
Nektar::Utilities::OutputGmsh Class Reference

Converter for Gmsh files. More...

#include <OutputGmsh.h>

Inheritance diagram for Nektar::Utilities::OutputGmsh:
Inheritance graph
[legend]
Collaboration diagram for Nektar::Utilities::OutputGmsh:
Collaboration graph
[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)
 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 boost::shared_ptr< Modulecreate (NekMeshUtils::MeshSharedPtr m)
 Creates an instance of this class. More...
 

Static Public Attributes

static NekMeshUtils::ModuleKey className
 

Private Attributes

boost::unordered_map
< NekMeshUtils::ElmtConfig,
unsigned int, ElmtConfigHash
elmMap
 

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,
ConfigOption
m_config
 List of configuration values. More...
 

Detailed Description

Converter for Gmsh files.

Definition at line 70 of file OutputGmsh.h.

Constructor & Destructor Documentation

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

Definition at line 56 of file OutputGmsh.cpp.

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

56  : OutputModule(m)
57 {
58  map<unsigned int, ElmtConfig> igelmap = InputGmsh::GenElmMap();
60 
61  // Populate #InputGmsh::elmMap and use this to construct an
62  // inverse mapping from %ElmtConfig to Gmsh ID.
63  for (it = igelmap.begin(); it != igelmap.end(); ++it)
64  {
65  elmMap[it->second] = it->first;
66  }
67 
68  m_config["order"] = ConfigOption(false, "-1", "Enforce a polynomial order");
69 }
boost::unordered_map< NekMeshUtils::ElmtConfig, unsigned int, ElmtConfigHash > elmMap
Definition: OutputGmsh.h:86
Represents a command-line configuration option.
std::map< std::string, ConfigOption > m_config
List of configuration values.
NEKMESHUTILS_EXPORT OutputModule(MeshSharedPtr p_m)
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
static std::map< unsigned int, NekMeshUtils::ElmtConfig > GenElmMap()
Definition: InputGmsh.cpp:1685
Nektar::Utilities::OutputGmsh::~OutputGmsh ( )
virtual

Definition at line 71 of file OutputGmsh.cpp.

72 {
73 }

Member Function Documentation

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

Creates an instance of this class.

Definition at line 74 of file OutputGmsh.h.

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

74  {
76  }
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
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 85 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::iterator, 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.

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

Member Data Documentation

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

Definition at line 77 of file OutputGmsh.h.

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

Definition at line 86 of file OutputGmsh.h.

Referenced by OutputGmsh(), and Process().