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

#include <InputNek.h>

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

Public Member Functions

 InputNek (MeshSharedPtr p_m)
 
virtual ~InputNek ()
 
virtual void Process ()
 Processes Nektar file format. More...
 
- Public Member Functions inherited from Nektar::Utilities::InputModule
 InputModule (FieldSharedPtr p_m)
 
void AddFile (string fileType, string fileName)
 
 InputModule (MeshSharedPtr p_m)
 
void OpenStream ()
 Open a file for input. More...
 
- Public Member Functions inherited from Nektar::Utilities::Module
 Module (FieldSharedPtr p_f)
 
virtual void Process (po::variables_map &vm)=0
 
void RegisterConfig (string key, string value)
 Register a configuration option with a module. More...
 
void PrintConfig ()
 Print out all configuration options for a module. More...
 
void SetDefaults ()
 Sets default configuration options for those which have not been set. More...
 
bool GetRequireEquiSpaced (void)
 
void SetRequireEquiSpaced (bool pVal)
 
void EvaluateTriFieldAtEquiSpacedPts (LocalRegions::ExpansionSharedPtr &exp, const Array< OneD, const NekDouble > &infield, Array< OneD, NekDouble > &outfield)
 
 Module (MeshSharedPtr p_m)
 
void RegisterConfig (string key, string value)
 
void PrintConfig ()
 
void SetDefaults ()
 
MeshSharedPtr GetMesh ()
 
virtual void ProcessVertices ()
 Extract element vertices. More...
 

Static Public Member Functions

static ModuleSharedPtr create (MeshSharedPtr m)
 Creates an instance of this class. More...
 

Static Public Attributes

static ModuleKey className
 ModuleKey for class. More...
 

Private Member Functions

void LoadHOSurfaces ()
 
int GetNnodes (LibUtilities::ShapeType elType)
 

Private Attributes

std::map< string, pair< NekCurve, string > > curveTags
 
std::map< string, HOSurfSethoData
 
std::map< int, int > hoMap
 

Additional Inherited Members

- Protected Member Functions inherited from Nektar::Utilities::InputModule
void PrintSummary ()
 Print summary of elements. More...
 
void PrintSummary ()
 Print summary of elements. More...
 
- Protected Member Functions inherited from Nektar::Utilities::Module
 Module ()
 
virtual void ProcessEdges (bool ReprocessEdges=true)
 Extract element edges. More...
 
virtual void ProcessFaces (bool ReprocessFaces=true)
 Extract element faces. More...
 
virtual void ProcessElements ()
 Generate element IDs. More...
 
virtual void ProcessComposites ()
 Generate composites. More...
 
void ReorderPrisms (PerMap &perFaces)
 Reorder node IDs so that prisms and tetrahedra are aligned correctly. More...
 
void PrismLines (int prism, PerMap &perFaces, set< int > &prismsDone, vector< ElementSharedPtr > &line)
 
- Protected Attributes inherited from Nektar::Utilities::InputModule
set< string > m_allowedFiles
 
std::ifstream m_mshFile
 Input stream. More...
 
- Protected Attributes inherited from Nektar::Utilities::Module
FieldSharedPtr m_f
 Field object. More...
 
map< string, ConfigOptionm_config
 List of configuration values. More...
 
bool m_requireEquiSpaced
 
MeshSharedPtr m_mesh
 Mesh object. More...
 

Detailed Description

Converter class for Nektar session files.

Definition at line 83 of file InputNek.h.

Constructor & Destructor Documentation

Nektar::Utilities::InputNek::InputNek ( MeshSharedPtr  p_m)

Definition at line 57 of file InputNek.cpp.

57  : InputModule(m)
58  {
59 
60  }
Nektar::Utilities::InputNek::~InputNek ( )
virtual

Definition at line 62 of file InputNek.cpp.

63  {
64 
65  }

Member Function Documentation

static ModuleSharedPtr Nektar::Utilities::InputNek::create ( MeshSharedPtr  m)
inlinestatic

Creates an instance of this class.

Definition at line 91 of file InputNek.h.

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

91  {
93  }
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
int Nektar::Utilities::InputNek::GetNnodes ( LibUtilities::ShapeType  InputNekEntity)
private

This routine aids the reading of Nektar files only; it returns the number of nodes for a given entity typw.

Definition at line 1059 of file InputNek.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 Process().

1060  {
1061  int nNodes = 0;
1062 
1063  switch(InputNekEntity)
1064  {
1065  case LibUtilities::ePoint: nNodes = 1; break;
1066  case LibUtilities::eSegment: nNodes = 2; break;
1067  case LibUtilities::eTriangle: nNodes = 3; break;
1068  case LibUtilities::eQuadrilateral: nNodes = 4; break;
1069  case LibUtilities::eTetrahedron: nNodes = 4; break;
1070  case LibUtilities::ePyramid: nNodes = 5; break;
1071  case LibUtilities::ePrism: nNodes = 6; break;
1072  case LibUtilities::eHexahedron: nNodes = 8; break;
1073  default:
1074  cerr << "unknown Nektar element type" << endl;
1075  }
1076 
1077  return nNodes;
1078  }
void Nektar::Utilities::InputNek::LoadHOSurfaces ( )
private

Load high order surface information from hsf file.

Definition at line 897 of file InputNek.cpp.

References curveTags, Nektar::Utilities::eFile, Nektar::LibUtilities::eNodalTriElec, hoData, hoMap, Nektar::iterator, Nektar::Utilities::Module::m_mesh, and Nektar::LibUtilities::PointsManager().

Referenced by Process().

898  {
899  map<string, pair<NekCurve, string> >::iterator it;
900  int nodeId = m_mesh->GetNumEntities();
901 
902  for (it = curveTags.begin(); it != curveTags.end(); ++it)
903  {
904  ifstream hsf;
905  string line, fileName = it->second.second;
906  size_t pos;
907  int N, Nface, dot;
908 
909  if (it->second.first != eFile)
910  {
911  continue;
912  }
913 
914  // Replace fro extension with hsf.
915  dot = fileName.find_last_of('.');
916  fileName = fileName.substr(0,dot);
917  fileName += ".hsf";
918 
919  // Open hsf file.
920  hsf.open(fileName.c_str());
921  if (!hsf.is_open())
922  {
923  cerr << "Could not open surface file " << fileName << endl;
924  abort();
925  }
926 
927  // Read in header line; determine element order, number of faces
928  // from this line.
929  getline(hsf, line);
930  pos = line.find("=");
931  if (pos == string::npos)
932  {
933  cerr << "hsf header error: cannot read number of "
934  << "nodal points." << endl;
935  abort();
936  }
937  line = line.substr(pos+1);
938  stringstream ss(line);
939  ss >> N;
940 
941  pos = line.find("=");
942  if (pos == string::npos)
943  {
944  cerr << "hsf header error: cannot read number of "
945  << "faces." << endl;
946  abort();
947  }
948  line = line.substr(pos+1);
949  ss.clear(); ss.str(line);
950  ss >> Nface;
951 
952  int Ntot = N*(N+1)/2;
953 
954  // Skip a line, then read in r,s positions inside the next
955  // comments.
956  Array<OneD, NekDouble> r(Ntot), s(Ntot);
957  getline(hsf, line);
958 
959  for (int i = 0; i < 2; ++i)
960  {
961  string word;
962 
963  getline(hsf, line);
964  ss.clear(); ss.str(line);
965  ss >> word;
966 
967  if (word != "#")
968  {
969  cerr << "hsf header error: cannot read in "
970  << "r/s points" << endl;
971  abort();
972  }
973 
974  for (int j = 0; j < Ntot; ++j)
975  {
976  ss >> (i == 0 ? r[j] : s[j]);
977  }
978  }
979 
980  // Generate electrostatic points so that re-mapping array can
981  // be constructed.
982  Array<OneD, NekDouble> rp(Ntot), sp(Ntot);
983  LibUtilities::PointsKey elec(N, LibUtilities::eNodalTriElec);
984  LibUtilities::PointsManager()[elec]->GetPoints(rp,sp);
985 
986  // Expensively construct remapping array nodemap. This will
987  // map nodal ordering from hsf order to Nektar++ ordering
988  // (i.e. vertices followed by edges followed by interior
989  // points.)
990  for (int i = 0; i < Ntot; ++i)
991  {
992  for (int j = 0; j < Ntot; ++j)
993  {
994  if (fabs(r[i]-rp[j]) < 1e-5 && fabs(s[i]-sp[j]) < 1e-5)
995  {
996  hoMap[i] = j;
997  break;
998  }
999  }
1000  }
1001 
1002  // Skip variables line
1003  getline(hsf, line);
1004 
1005  // Read in nodal points for each face.
1006  map<int, vector<NodeSharedPtr> > faceMap;
1007  for (int i = 0; i < Nface; ++i)
1008  {
1009  getline(hsf, line);
1010  vector<NodeSharedPtr> faceNodes(Ntot);
1011  for (int j = 0; j < Ntot; ++j, ++nodeId)
1012  {
1013  double x, y, z;
1014  getline(hsf, line);
1015  ss.clear(); ss.str(line);
1016  ss >> x >> y >> z;
1017  faceNodes[j] = NodeSharedPtr(new Node(nodeId, x, y, z));
1018  }
1019  // Skip over tecplot connectivity information.
1020  for (int j = 0; j < (N-1)*(N-1); ++j)
1021  {
1022  getline(hsf, line);
1023  }
1024  faceMap[i] = faceNodes;
1025  }
1026 
1027  // Finally, read in connectivity information to set up after
1028  // reading rea file.
1029  getline(hsf, line);
1030  for (int i = 0; i < Nface; ++i)
1031  {
1032  string tmp;
1033  int fid;
1034  vector<int> nodeIds(3);
1035 
1036  getline(hsf, line);
1037  ss.clear(); ss.str(line);
1038  ss >> tmp >> fid >> nodeIds[0] >> nodeIds[1] >> nodeIds[2];
1039 
1040  if (tmp != "#")
1041  {
1042  cerr << "Unable to read hsf connectivity information."
1043  << endl;
1044  abort();
1045  }
1046 
1047  hoData[it->first].insert(
1048  HOSurfSharedPtr(new HOSurf(nodeIds, faceMap[i])));
1049  }
1050 
1051  hsf.close();
1052  }
1053  }
std::map< string, HOSurfSet > hoData
Definition: InputNek.h:109
boost::shared_ptr< HOSurf > HOSurfSharedPtr
Definition: InputNek.h:52
MeshSharedPtr m_mesh
Mesh object.
boost::shared_ptr< Node > NodeSharedPtr
Shared pointer to a Node.
Definition: MeshElements.h:195
std::map< int, int > hoMap
Definition: InputNek.h:114
HOTriangle< NodeSharedPtr > HOSurf
Definition: InputNek.h:51
std::map< string, pair< NekCurve, string > > curveTags
Definition: InputNek.h:104
PointsManagerT & PointsManager(void)
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
2D Nodal Electrostatic Points on a Triangle
Definition: PointsType.h:68
void Nektar::Utilities::InputNek::Process ( )
virtual

Processes Nektar file format.

Nektar sessions are defined by rea files, and contain sections defining a DNS simulation in a specific order. The converter only reads mesh information, curve information if it exists and boundary information.

Parameters
pFilenameFilename of Nektar session file to read.

Implements Nektar::Utilities::Module.

Definition at line 77 of file InputNek.cpp.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), curveTags, Nektar::Utilities::eDirichlet, Nektar::Utilities::eFile, Nektar::LibUtilities::eGaussLobattoLegendre, Nektar::LibUtilities::eHexahedron, Nektar::Utilities::eHOPCondition, Nektar::Utilities::eNeumann, Nektar::LibUtilities::eNodalTriElec, Nektar::LibUtilities::ePrism, Nektar::LibUtilities::ePyramid, Nektar::LibUtilities::eQuadrilateral, Nektar::Utilities::eRecon, Nektar::LibUtilities::eSegment, Nektar::LibUtilities::eTetrahedron, Nektar::LibUtilities::eTriangle, Nektar::Utilities::GetElementFactory(), GetNnodes(), Nektar::Utilities::Element::GetVertex(), hoData, hoMap, Nektar::iterator, LoadHOSurfaces(), Nektar::Utilities::Module::m_mesh, Nektar::Utilities::InputModule::m_mshFile, Nektar::Utilities::Tetrahedron::m_orientationMap, Nektar::Utilities::InputModule::OpenStream(), Nektar::Utilities::Module::ProcessComposites(), Nektar::Utilities::Module::ProcessEdges(), Nektar::Utilities::Module::ProcessElements(), and Nektar::Utilities::Module::ProcessFaces().

78  {
79  // Open the file stream.
80  OpenStream();
81 
82  string line, word;
83  int nParam, nElements, nCurves;
84  int i, j, k, nodeCounter = 0;
85  int nComposite = 0;
87  double vertex[3][8];
88  map<LibUtilities::ShapeType,int> domainComposite;
89  map<LibUtilities::ShapeType,vector< vector<NodeSharedPtr> > > elNodes;
90  map<LibUtilities::ShapeType,vector<int> > elIds;
91  boost::unordered_map<int,int> elMap;
92  vector<LibUtilities::ShapeType> elmOrder;
93 
94  // Set up vector of processing orders.
95  elmOrder.push_back(LibUtilities::eSegment);
96  elmOrder.push_back(LibUtilities::eTriangle);
97  elmOrder.push_back(LibUtilities::eQuadrilateral);
98  elmOrder.push_back(LibUtilities::ePrism);
99  elmOrder.push_back(LibUtilities::ePyramid);
100  elmOrder.push_back(LibUtilities::eTetrahedron);
101  elmOrder.push_back(LibUtilities::eHexahedron);
102 
103  m_mesh->m_expDim = 0;
104  m_mesh->m_spaceDim = 0;
105 
106  if (m_mesh->m_verbose)
107  {
108  cout << "InputNek: Start reading file..." << endl;
109  }
110 
111  // -- Read in parameters.
112 
113  // Ignore first 3 lines. 4th line contains number of parameters.
114  for (i = 0; i < 4; ++i)
115  {
116  getline(m_mshFile, line);
117  }
118 
119  stringstream s(line);
120  s >> nParam;
121 
122  for (i = 0; i < nParam; ++i)
123  {
124  string tmp1, tmp2;
125  getline(m_mshFile, line);
126  s.str(line);
127  s >> tmp1 >> tmp2;
128  }
129 
130  // -- Read in passive scalars (ignore)
131  getline(m_mshFile, line);
132  s.clear();
133  s.str(line);
134  s >> j;
135  for (i = 0; i < j; ++i)
136  {
137  getline(m_mshFile, line);
138  }
139 
140  // -- Read in logical switches (ignore)
141  getline(m_mshFile, line);
142  s.clear();
143  s.str(line);
144  s >> j;
145  for (i = 0; i < j; ++i)
146  {
147  getline(m_mshFile, line);
148  }
149 
150  // -- Read in mesh data.
151 
152  // First hunt for MESH tag
153  bool foundMesh = false;
154  while (!m_mshFile.eof())
155  {
156  getline(m_mshFile, line);
157  if (line.find("MESH") != string::npos)
158  {
159  foundMesh = true;
160  break;
161  }
162  }
163 
164  if (!foundMesh)
165  {
166  cerr << "Couldn't find MESH tag inside file." << endl;
167  abort();
168  }
169 
170  // Now read in number of elements and space dimension.
171  getline(m_mshFile, line);
172  s.clear(); s.str(line);
173  s >> nElements >> m_mesh->m_expDim;
174  m_mesh->m_spaceDim = m_mesh->m_expDim;
175 
176  // Set up field names.
177  m_mesh->m_fields.push_back("u");
178  m_mesh->m_fields.push_back("v");
179  if (m_mesh->m_spaceDim > 2)
180  {
181  m_mesh->m_fields.push_back("w");
182  }
183  m_mesh->m_fields.push_back("p");
184 
185  // Loop over and create elements.
186  for (i = 0; i < nElements; ++i)
187  {
188  getline(m_mshFile, line);
189 
190  if (m_mesh->m_expDim == 2)
191  {
192  if (line.find("Qua") != string::npos ||
193  line.find("qua") != string::npos)
194  {
196  }
197  else
198  {
199  // Default element type in 2D is triangle.
200  elType = LibUtilities::eTriangle;
201  }
202  }
203  else
204  {
205  if (line.find("Tet") != string::npos ||
206  line.find("tet") != string::npos)
207  {
209  }
210  else if (line.find("Hex") != string::npos ||
211  line.find("hex") != string::npos)
212  {
213  elType = LibUtilities::eHexahedron;
214  }
215  else if (line.find("Prism") != string::npos ||
216  line.find("prism") != string::npos)
217  {
218  elType = LibUtilities::ePrism;
219  }
220  else if (line.find("Pyr") != string::npos ||
221  line.find("pyr") != string::npos)
222  {
223  elType = LibUtilities::ePyramid;
224  }
225  else if (line.find("Qua") != string::npos ||
226  line.find("qua") != string::npos)
227  {
229  }
230  else
231  {
232  // Default element type in 2D is tetrahedron.
234  }
235  }
236 
237  // Read in number of vertices for element type.
238  const int nNodes = GetNnodes(elType);
239 
240  for (j = 0; j < m_mesh->m_expDim; ++j)
241  {
242  getline(m_mshFile,line);
243  s.clear(); s.str(line);
244  for (k = 0; k < nNodes; ++k)
245  {
246  s >> vertex[j][k];
247  }
248  }
249 
250  // Zero co-ordinates bigger than expansion dimension.
251  for (j = m_mesh->m_expDim; j < 3; ++j)
252  {
253  for (k = 0; k < nNodes; ++k)
254  {
255  vertex[j][k] = 0.0;
256  }
257  }
258 
259  // Nektar meshes do not contain a unique list of nodes, so this
260  // block constructs a unique set so that elements can be created
261  // with unique nodes.
262  vector<NodeSharedPtr> nodeList;
263  for (k = 0; k < nNodes; ++k)
264  {
265  NodeSharedPtr n = boost::shared_ptr<Node>(
266  new Node(nodeCounter++, vertex[0][k],
267  vertex[1][k], vertex[2][k]));
268  nodeList.push_back(n);
269  }
270 
271  elNodes[elType].push_back(nodeList);
272  elIds [elType].push_back(i);
273  }
274 
275  int reorderedId = 0;
276  nodeCounter = 0;
277 
278  for (i = 0; i < elmOrder.size(); ++i)
279  {
280  LibUtilities::ShapeType elType = elmOrder[i];
281  vector<vector<NodeSharedPtr> > &tmp = elNodes[elType];
282 
283  for (j = 0; j < tmp.size(); ++j)
284  {
285  vector<int> tags;
287  domainComposite.find(elType);
288  if (compIt == domainComposite.end())
289  {
290  tags.push_back(nComposite);
291  domainComposite[elType] = nComposite;
292  nComposite++;
293  }
294  else
295  {
296  tags.push_back(compIt->second);
297  }
298 
299  elMap[elIds[elType][j]] = reorderedId++;
300 
301  vector<NodeSharedPtr> nodeList = tmp[j];
302 
303  for (k = 0; k < nodeList.size(); ++k)
304  {
305  pair<NodeSet::iterator, bool> testIns =
306  m_mesh->m_vertexSet.insert(nodeList[k]);
307 
308  if (!testIns.second)
309  {
310  nodeList[k] = *(testIns.first);
311  }
312  else
313  {
314  nodeList[k]->m_id = nodeCounter++;
315  }
316  }
317 
318  // Create linear element
319  ElmtConfig conf(elType,1,false,false);
321  CreateInstance(elType,conf,nodeList,tags);
322  m_mesh->m_element[E->GetDim()].push_back(E);
323  }
324  }
325 
326  // -- Read in curved data.
327  getline(m_mshFile, line);
328  if (line.find("CURVE") == string::npos)
329  {
330  cerr << "Cannot find curved side data." << endl;
331  abort();
332  }
333 
334  // Read number of curves.
335  getline(m_mshFile, line);
336  s.clear(); s.str(line);
337  s >> nCurves;
338 
339  if (nCurves > 0)
340  {
341  string curveTag;
342 
343  for (i = 0; i < nCurves; ++i)
344  {
345  getline(m_mshFile, line);
346  s.clear(); s.str(line);
347  s >> word;
348 
349  if (word == "File")
350  {
351  // Next line contains filename and curve tag.
352  getline(m_mshFile, line);
353  s.clear(); s.str(line);
354  s >> word >> curveTag;
355  curveTags[curveTag] = make_pair(eFile, word);
356  }
357  else if (word == "Recon")
358  {
359  // Next line contains curve tag.
360  getline(m_mshFile, line);
361  s.clear(); s.str(line);
362  s >> word >> curveTag;
363  curveTags[curveTag] = make_pair(eRecon, word);
364  }
365  else
366  {
367  cerr << "Unsupported curve type " << word << endl;
368  abort();
369  }
370  }
371 
372  // Load high order surface information.
373  LoadHOSurfaces();
374 
375  // Read in curve information. First line should contain number
376  // of curved sides.
377  getline(m_mshFile,line);
378 
379  if (line.find("side") == string::npos)
380  {
381  cerr << "Unable to read number of curved sides" << endl;
382  abort();
383  }
384 
385  int nCurvedSides;
386  int faceId, elId;
387  map<string,pair<NekCurve, string> >::iterator it;
388  HOSurfSet::iterator hoIt;
389 
390  s.clear(); s.str(line);
391  s >> nCurvedSides;
392 
393  // Iterate over curved sides, and look up high-order surface
394  // information in the HOSurfSet, then map this onto faces.
395  for (i = 0; i < nCurvedSides; ++i)
396  {
397  getline(m_mshFile, line);
398  s.clear(); s.str(line);
399  s >> faceId >> elId >> word;
400  faceId--;
401  elId = elMap[elId-1];
402  ElementSharedPtr el = m_mesh->m_element[m_mesh->m_expDim][elId];
403 
404  int origFaceId = faceId;
405 
406  if (el->GetConf().m_e == LibUtilities::ePrism && faceId % 2 == 0)
407  {
408  boost::shared_ptr<Prism> p =
409  boost::dynamic_pointer_cast<Prism>(el);
410  if (p->m_orientation == 1)
411  {
412  faceId = (faceId+2) % 6;
413  }
414  else if (p->m_orientation == 2)
415  {
416  faceId = (faceId+4) % 6;
417  }
418  }
419  else if (el->GetConf().m_e == LibUtilities::eTetrahedron)
420  {
421  boost::shared_ptr<Tetrahedron> t =
422  boost::dynamic_pointer_cast<Tetrahedron>(el);
423  faceId = t->m_orientationMap[faceId];
424  }
425 
426  it = curveTags.find(word);
427  if (it == curveTags.end())
428  {
429  cerr << "Unrecognised curve tag " << word
430  << " in curved lines" << endl;
431  abort();
432  }
433 
434  if (it->second.first == eRecon)
435  {
436  // Spherigon information: read in vertex normals.
437  vector<NodeSharedPtr> &tmp =
438  el->GetFace(faceId)->m_vertexList;
439  vector<Node> n(tmp.size());
440 
441  int offset = 0;
442  if (el->GetConf().m_e == LibUtilities::ePrism && faceId % 2 == 1)
443  {
444  offset = boost::dynamic_pointer_cast<Prism>(
445  el)->m_orientation;
446  }
447 
448  // Read x/y/z coordinates.
449  getline(m_mshFile, line);
450  s.clear(); s.str(line);
451  for (j = 0; j < tmp.size(); ++j)
452  {
453  s >> n[j].m_x;
454  }
455 
456  getline(m_mshFile, line);
457  s.clear(); s.str(line);
458  for (j = 0; j < tmp.size(); ++j)
459  {
460  s >> n[j].m_y;
461  }
462 
463  getline(m_mshFile, line);
464  s.clear(); s.str(line);
465  for (j = 0; j < tmp.size(); ++j)
466  {
467  s >> n[j].m_z;
468  }
469 
470  for (j = 0; j < tmp.size(); ++j)
471  {
472  int id = tmp[(j+offset) % tmp.size()]->m_id;
474  m_mesh->m_vertexNormals.find(id);
475 
476  if (vIt == m_mesh->m_vertexNormals.end())
477  {
478  m_mesh->m_vertexNormals[id] = n[j];
479  }
480  }
481 
482  // Add edge/face to list of faces to apply spherigons
483  // to.
484  m_mesh->m_spherigonSurfs.insert(make_pair(elId, faceId));
485  }
486  else if (it->second.first == eFile)
487  {
488  FaceSharedPtr f = el->GetFace(faceId);
489  static int tetFaceVerts[4][3] = {
490  {0,1,2},{0,1,3},{1,2,3},{0,2,3}};
491 
492  vector<int> vertId(3);
493  s >> vertId[0] >> vertId[1] >> vertId[2];
494 
495  // Prisms and tets may have been rotated by OrientPrism
496  // routine which reorders vertices. This block rotates
497  // vertex ids accordingly.
498  if (el->GetConf().m_e == LibUtilities::eTetrahedron)
499  {
500  boost::shared_ptr<Tetrahedron> tet =
501  boost::static_pointer_cast<Tetrahedron>(el);
502  vector<int> tmpVertId = vertId;
503 
504  for (j = 0; j < 3; ++j)
505  {
506  int v = tet->GetVertex(
507  tet->m_origVertMap[
508  tetFaceVerts[origFaceId][j]])->m_id;
509 
510  for (k = 0; k < 3; ++k)
511  {
512  int w = f->m_vertexList[k]->m_id;
513  if (v == w)
514  {
515  vertId[k] = tmpVertId[j];
516  break;
517  }
518  }
519  }
520  }
521  else if (el->GetConf().m_e == LibUtilities::ePrism)
522  {
523  boost::shared_ptr<Prism> pr =
524  boost::static_pointer_cast<Prism>(el);
525  if (pr->m_orientation == 1)
526  {
527  swap(vertId[2], vertId[1]);
528  swap(vertId[0], vertId[1]);
529  }
530  else if (pr->m_orientation == 2)
531  {
532  swap(vertId[0], vertId[1]);
533  swap(vertId[2], vertId[1]);
534  }
535  }
536 
537  // Find vertex combination in hoData.
538  hoIt = hoData[word].find(HOSurfSharedPtr(
539  new HOSurf(vertId)));
540 
541  if (hoIt == hoData[word].end())
542  {
543  cerr << "Unable to find high-order surface data "
544  << "for element id " << elId+1 << endl;
545  abort();
546  }
547 
548  // Depending on order of vertices in rea file, surface
549  // information may need to be rotated or reflected.
550  HOSurfSharedPtr surf = *hoIt;
551  surf->Align(vertId);
552 
553  // Finally, add high order data to appropriate face.
554  int Ntot = (*hoIt)->surfVerts.size();
555  int N = ((int)sqrt(8.0*Ntot+1.0)-1)/2;
556  EdgeSharedPtr edge;
557 
558  // Apply high-order map to convert face data to Nektar++
559  // ordering (vertices->edges->internal).
560  vector<NodeSharedPtr> tmpVerts = (*hoIt)->surfVerts;
561  for (j = 0; j < tmpVerts.size(); ++j)
562  {
563  (*hoIt)->surfVerts[hoMap[j]] = tmpVerts[j];
564  }
565 
566  for (j = 0; j < tmpVerts.size(); ++j)
567  {
568  NodeSharedPtr a = (*hoIt)->surfVerts[j];
569  }
570 
571  vector<int> faceVertIds(3);
572  faceVertIds[0] = f->m_vertexList[0]->m_id;
573  faceVertIds[1] = f->m_vertexList[1]->m_id;
574  faceVertIds[2] = f->m_vertexList[2]->m_id;
575 
576  for (j = 0; j < f->m_edgeList.size(); ++j)
577  {
578  edge = f->m_edgeList[j];
579 
580  // Skip over edges which have already been
581  // populated.
582  if (edge->m_edgeNodes.size() > 0)
583  {
584  continue;
585  }
586 
587  //edge->m_edgeNodes.clear();
588  edge->m_curveType
590 
591  for (int k = 0; k < N-2; ++k)
592  {
593  edge->m_edgeNodes.push_back(
594  (*hoIt)->surfVerts[3+j*(N-2)+k]);
595  }
596 
597  // Nodal triangle data is always
598  // counter-clockwise. Add this check to reorder
599  // where necessary.
600  if (edge->m_n1->m_id != faceVertIds[j])
601  {
602  reverse(edge->m_edgeNodes.begin(),
603  edge->m_edgeNodes.end());
604  }
605  }
606 
607  // Insert interior face curvature.
608  f->m_curveType = LibUtilities::eNodalTriElec;
609  for (int j = 3+3*(N-2); j < Ntot; ++j)
610  {
611  f->m_faceNodes.push_back((*hoIt)->surfVerts[j]);
612  }
613  }
614  }
615  }
616 
617  // -- Process fluid boundary conditions.
618 
619  // Define a fairly horrendous map: key is the condition ID, the
620  // value is a vector of pairs of composites and element
621  // types. Essentially this map takes conditions -> composites for
622  // each element type.
623  map<int,vector<pair<int,LibUtilities::ShapeType> > > surfaceCompMap;
624 
625  // Skip boundary conditions line.
626  getline(m_mshFile, line);
627  getline(m_mshFile, line);
628 
629  int nSurfaces = 0;
630 
631  while (true)
632  {
633  getline(m_mshFile, line);
634 
635  // Break out of loop at end of boundary conditions section.
636  if (line.find("*") != string::npos || m_mshFile.eof() ||
637  line.length() == 0)
638  {
639  break;
640  }
641 
642  // Read boundary type, element ID and face ID.
643  char bcType;
644  int elId, faceId;
645  s.clear(); s.str(line);
646  s >> bcType >> elId >> faceId;
647  faceId--;
648  elId = elMap[elId-1];
649 
650  vector<string> vals;
651  vector<ConditionType> type;
652  ConditionSharedPtr c =
654 
655  // First character on each line describes type of BC. Currently
656  // only support V, W, and O. In this switch statement we
657  // construct the quantities needed to search for the condition.
658  switch(bcType)
659  {
660  // Wall boundary.
661  case 'W':
662  {
663  for (i = 0; i < m_mesh->m_fields.size()-1; ++i)
664  {
665  vals.push_back("0");
666  type.push_back(eDirichlet);
667  }
668  // Set high-order boundary condition for wall.
669  vals.push_back("0");
670  type.push_back(eHOPCondition);
671  break;
672  }
673 
674  // Velocity boundary condition (either constant or dependent
675  // upon x,y,z).
676  case 'V':
677  case 'v':
678  {
679  for (i = 0; i < m_mesh->m_fields.size()-1; ++i)
680  {
681  getline(m_mshFile, line);
682  size_t p = line.find_first_of('=');
683  vals.push_back(boost::algorithm::trim_copy(
684  line.substr(p+1)));
685  type.push_back(eDirichlet);
686  }
687  // Set high-order boundary condition for Dirichlet
688  // condition.
689  vals.push_back("0");
690  type.push_back(eHOPCondition);
691  break;
692  }
693 
694  // Natural outflow condition (default value = 0.0?)
695  case 'O':
696  {
697  for (i = 0; i < m_mesh->m_fields.size(); ++i)
698  {
699  vals.push_back("0");
700  type.push_back(eNeumann);
701  }
702  // Set zero Dirichlet condition for outflow.
703  type[m_mesh->m_fields.size()-1] = eDirichlet;
704  break;
705  }
706 
707  // Ignore unsupported BCs
708  case 'P':
709  case 'E':
710  case 'F':
711  case 'f':
712  case 'N':
713  continue;
714  break;
715 
716  default:
717  cerr << "Unknown boundary condition type "
718  << line[0] << endl;
719  abort();
720  }
721 
722  // Populate condition information.
723  c->field = m_mesh->m_fields;
724  c->type = type;
725  c->value = vals;
726 
727  // Now attempt to find this boundary condition inside
728  // m_mesh->condition. This is currently a linear search and should
729  // probably be made faster!
731  bool found = false;
732  for (it = m_mesh->m_condition.begin(); it != m_mesh->m_condition.end(); ++it)
733  {
734  if (c == it->second)
735  {
736  found = true;
737  break;
738  }
739  }
740 
741  int compTag, conditionId;
742  ElementSharedPtr elm = m_mesh->m_element[m_mesh->m_spaceDim][elId];
743  ElementSharedPtr surfEl;
744 
745  // Create element for face (3D) or segment (2D). At the moment
746  // this is a bit of a hack since high-order nodes are not
747  // copied, so some output modules (e.g. Gmsh) will not output
748  // correctly.
749  if (elm->GetDim() == 3)
750  {
751  // 3D elements may have been reoriented, so face IDs will
752  // change.
753  if (elm->GetConf().m_e == LibUtilities::ePrism && faceId % 2 == 0)
754  {
755  boost::shared_ptr<Prism> p =
756  boost::dynamic_pointer_cast<Prism>(elm);
757  if (p->m_orientation == 1)
758  {
759  faceId = (faceId+2) % 6;
760  }
761  else if (p->m_orientation == 2)
762  {
763  faceId = (faceId+4) % 6;
764  }
765  }
766  else if (elm->GetConf().m_e == LibUtilities::eTetrahedron)
767  {
768  boost::shared_ptr<Tetrahedron> t =
769  boost::dynamic_pointer_cast<Tetrahedron>(elm);
770  faceId = t->m_orientationMap[faceId];
771  }
772 
773  FaceSharedPtr f = elm->GetFace(faceId);
774  bool tri = f->m_vertexList.size() == 3;
775 
776  vector<NodeSharedPtr> nodeList;
777  nodeList.insert(nodeList.begin(),
778  f->m_vertexList.begin(),
779  f->m_vertexList.end());
780 
781  vector<int> tags;
782 
785  ElmtConfig conf(seg,1,true,true,false,
787  surfEl = GetElementFactory().
788  CreateInstance(seg,conf,nodeList,tags);
789 
790  // Copy high-order surface information from edges.
791  for (int i = 0; i < f->m_vertexList.size(); ++i)
792  {
793  surfEl->GetEdge(i)->m_edgeNodes =
794  f->m_edgeList[i]->m_edgeNodes;
795  surfEl->GetEdge(i)->m_curveType =
796  f->m_edgeList[i]->m_curveType;
797  }
798  }
799  else
800  {
801  EdgeSharedPtr f = elm->GetEdge(faceId);
802 
803  vector<NodeSharedPtr> nodeList;
804  nodeList.push_back(f->m_n1);
805  nodeList.push_back(f->m_n2);
806 
807  vector<int> tags;
808 
809  ElmtConfig conf(LibUtilities::eSegment,1,true,true,false,
811  surfEl = GetElementFactory().
812  CreateInstance(LibUtilities::eSegment,conf,nodeList,tags);
813  }
814 
815  LibUtilities::ShapeType surfElType = surfEl->GetConf().m_e;
816 
817  if (!found)
818  {
819  // If condition does not already exist, add to condition
820  // list, create new composite tag and put inside
821  // surfaceCompMap.
822  conditionId = m_mesh->m_condition.size();
823  compTag = nComposite;
824  c->m_composite.push_back(compTag);
825  m_mesh->m_condition[conditionId] = c;
826 
827  surfaceCompMap[conditionId].push_back(
828  pair<int,LibUtilities::ShapeType>(nComposite,surfElType));
829 
830  nComposite++;
831  }
832  else
833  {
834  // Otherwise find existing composite inside surfaceCompMap.
835  map<int,vector<pair<int,LibUtilities::ShapeType> > >::iterator it2;
836  it2 = surfaceCompMap.find(it->first);
837 
838  found = false;
839  if (it2 == surfaceCompMap.end())
840  {
841  // This should never happen!
842  cerr << "Unable to find condition!" << endl;
843  abort();
844  }
845 
846  for (j = 0; j < it2->second.size(); ++j)
847  {
848  pair<int,LibUtilities::ShapeType> tmp = it2->second[j];
849  if (tmp.second == surfElType)
850  {
851  found = true;
852  compTag = tmp.first;
853  break;
854  }
855  }
856 
857  // If no pairs were found, then this condition contains
858  // multiple element types (i.e. both triangles and
859  // quads). Create another composite for the new shape type
860  // and insert into the map.
861  if (!found)
862  {
863  it2->second.push_back(pair<int,LibUtilities::ShapeType>(
864  nComposite,surfElType));
865  compTag = nComposite;
866  m_mesh->m_condition[it->first]->m_composite.push_back(compTag);
867  nComposite++;
868  }
869 
870  conditionId = it->first;
871  }
872 
873  // Insert composite tag into element and insert element into
874  // mesh.
875  vector<int> existingTags = surfEl->GetTagList();
876 
877  existingTags.insert(existingTags.begin(), compTag);
878  surfEl->SetTagList (existingTags);
879  surfEl->SetId (nSurfaces);
880 
881  m_mesh->m_element[surfEl->GetDim()].push_back(surfEl);
882  nSurfaces++;
883  }
884 
885  m_mshFile.close();
886 
887  // -- Process rest of mesh.
888  ProcessEdges ();
889  ProcessFaces ();
890  ProcessElements ();
892  }
std::ifstream m_mshFile
Input stream.
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
std::map< string, HOSurfSet > hoData
Definition: InputNek.h:109
boost::shared_ptr< HOSurf > HOSurfSharedPtr
Definition: InputNek.h:52
boost::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
Definition: MeshElements.h:318
MeshSharedPtr m_mesh
Mesh object.
boost::shared_ptr< Face > FaceSharedPtr
Shared pointer to a face.
Definition: MeshElements.h:550
boost::shared_ptr< Node > NodeSharedPtr
Shared pointer to a Node.
Definition: MeshElements.h:195
virtual void ProcessEdges(bool ReprocessEdges=true)
Extract element edges.
boost::shared_ptr< Condition > ConditionSharedPtr
boost::shared_ptr< Element > ElementSharedPtr
Shared pointer to an element.
Definition: MeshElements.h:63
std::map< int, int > hoMap
Definition: InputNek.h:114
virtual void ProcessElements()
Generate element IDs.
HOTriangle< NodeSharedPtr > HOSurf
Definition: InputNek.h:51
std::map< string, pair< NekCurve, string > > curveTags
Definition: InputNek.h:104
virtual void ProcessComposites()
Generate composites.
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
int GetNnodes(LibUtilities::ShapeType elType)
Definition: InputNek.cpp:1059
virtual void ProcessFaces(bool ReprocessFaces=true)
Extract element faces.
void OpenStream()
Open a file for input.
ElementFactory & GetElementFactory()
1D Gauss-Lobatto-Legendre quadrature points
Definition: PointsType.h:50
2D Nodal Electrostatic Points on a Triangle
Definition: PointsType.h:68

Member Data Documentation

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

ModuleKey for class.

Definition at line 95 of file InputNek.h.

std::map<string, pair<NekCurve, string> > Nektar::Utilities::InputNek::curveTags
private

Maps a curve tag to a filename containing surface information.

Definition at line 104 of file InputNek.h.

Referenced by LoadHOSurfaces(), and Process().

std::map<string, HOSurfSet> Nektar::Utilities::InputNek::hoData
private

Maps a curve tag to the high-order surface data for that tag.

Definition at line 109 of file InputNek.h.

Referenced by LoadHOSurfaces(), and Process().

std::map<int, int> Nektar::Utilities::InputNek::hoMap
private

Maps ordering of hsf standard element to Nektar++ ordering.

Definition at line 114 of file InputNek.h.

Referenced by LoadHOSurfaces(), and Process().