Nektar++
InputNekpp.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: InputNekpp.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: GMSH converter.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #include <string>
37 #include <iostream>
38 using namespace std;
39 
41 
42 #include "../MeshElements.h"
43 #include "InputNekpp.h"
44 
45 namespace Nektar
46 {
47  namespace Utilities
48  {
49  ModuleKey InputNekpp::className =
51  ModuleKey(eInputModule, "xml"), InputNekpp::create,
52  "Reads Nektar++ xml file.");
53 
54  /**
55  * @brief Set up InputNekpp object.
56  */
57  InputNekpp::InputNekpp(MeshSharedPtr m) : InputModule(m)
58  {
59 
60  }
61 
63  {
64 
65  }
66 
67  /**
68  * Gmsh file contains a list of nodes and their coordinates, along with
69  * a list of elements and those nodes which define them. We read in and
70  * store the list of nodes in #m_node and store the list of elements in
71  * #m_element. Each new element is supplied with a list of entries from
72  * #m_node which defines the element. Finally some mesh statistics are
73  * printed.
74  *
75  * @param pFilename Filename of Gmsh file to read.
76  */
78  {
79  vector<string> filename;
80  filename.push_back(m_config["infile"].as<string>());
81 
86 
87  m_mesh->m_expDim = graph->GetMeshDimension ();
88  m_mesh->m_spaceDim = graph->GetSpaceDimension();
89 
90  // Copy vertices.
91  map<int, NodeSharedPtr> vIdMap;
92  int nVerts = graph->GetNvertices();
93  for (int i = 0; i < nVerts; ++i)
94  {
96  graph->GetVertex(i);
97  NodeSharedPtr n(new Node(vert->GetVid(),
98  (*vert)(0), (*vert)(1), (*vert)(2)));
99  m_mesh->m_vertexSet.insert(n);
100  vIdMap[vert->GetVid()] = n;
101  }
102 
103  map<int, EdgeSharedPtr> eIdMap;
105  map<int, FaceSharedPtr> fIdMap;
107 
108  // Load up all edges from graph
109  {
110  int nel = 0;
111  SpatialDomains::SegGeomMap tmp = graph->GetAllSegGeoms();
113  pair<EdgeSet::iterator,bool> testIns;
114  nel += tmp.size();
115 
116  for (it = tmp.begin(); it != tmp.end(); ++it)
117  {
118  pair<int, SpatialDomains::GeometrySharedPtr> tmp2(
119  it->first, boost::dynamic_pointer_cast<
120  SpatialDomains::Geometry>(it->second));
121 
122  // load up edge set in order of SegGeomMap;
123  vector<NodeSharedPtr> curve; // curved nodes if deformed
124  int id0 = it->second->GetVid(0);
125  int id1 = it->second->GetVid(1);
126  LibUtilities::PointsType ptype = it->second->GetPointsKeys()[0].GetPointsType();
127  EdgeSharedPtr ed = EdgeSharedPtr(new Edge(vIdMap[id0], vIdMap[id1],
128  curve, ptype));
129 
130  testIns = m_mesh->m_edgeSet.insert(ed);
131  (*(testIns.first))->m_id = it->second->GetEid();
132  eIdMap[it->second->GetEid()] = ed;
133  }
134  }
135 
136 
137  // load up all faces from graph
138  {
139  int nel = 0;
140  SpatialDomains::TriGeomMap tmp = graph->GetAllTriGeoms();
142  pair<FaceSet::iterator,bool> testIns;
143  nel += tmp.size();
144 
145  for (it = tmp.begin(); it != tmp.end(); ++it)
146  {
147  pair<int, SpatialDomains::GeometrySharedPtr> tmp2(
148  it->first, boost::dynamic_pointer_cast<
149  SpatialDomains::Geometry>(it->second));
150 
151  vector<NodeSharedPtr> faceVertices;
152  vector<EdgeSharedPtr> faceEdges;
153  vector<NodeSharedPtr> faceNodes;
154 
155  for(int i = 0; i < 3; ++i)
156  {
157  faceVertices.push_back(vIdMap[it->second->GetVid(i)]);
158  faceEdges.push_back(eIdMap[it->second->GetEid(i)]);
159  }
160 
161  FaceSharedPtr fac = FaceSharedPtr( new Face(faceVertices,faceNodes,faceEdges,
163  testIns = m_mesh->m_faceSet.insert(fac);
164  (*(testIns.first))->m_id = it->second->GetFid();
165  fIdMap[it->second->GetFid()] = fac;
166  }
167 
168  SpatialDomains::QuadGeomMap tmp3 = graph->GetAllQuadGeoms();
170 
171  for (it2 = tmp3.begin(); it2 != tmp3.end(); ++it2)
172  {
173  pair<int, SpatialDomains::GeometrySharedPtr> tmp2(
174  it2->first, boost::dynamic_pointer_cast<
175  SpatialDomains::Geometry>(it2->second));
176 
177  vector<NodeSharedPtr> faceVertices;
178  vector<EdgeSharedPtr> faceEdges;
179  vector<NodeSharedPtr> faceNodes;
180 
181  for(int i = 0; i < 4; ++i)
182  {
183  faceVertices.push_back(vIdMap[it2->second->GetVid(i)]);
184  faceEdges.push_back(eIdMap[it2->second->GetEid(i)]);
185  }
186 
187  FaceSharedPtr fac = FaceSharedPtr( new Face(faceVertices,faceNodes,faceEdges,
189  testIns = m_mesh->m_faceSet.insert(fac);
190  (*(testIns.first))->m_id = it2->second->GetFid();
191  fIdMap[it2->second->GetFid()] = fac;
192  }
193  }
194 
195  // Set up curved information
196 
197  // Curved Edges
198  SpatialDomains::CurveMap &curvedEdges = graph->GetCurvedEdges();
200 
201  for (it = curvedEdges.begin(); it != curvedEdges.end(); ++it)
202  {
203  SpatialDomains::CurveSharedPtr curve = it->second;
204  int id = curve->m_curveID;
205  ASSERTL1(eIdMap.find(id) != eIdMap.end(),
206  "Failed to find curved edge");
207  EdgeSharedPtr edg = eIdMap[id];
208  edg->m_curveType = curve->m_ptype;
209  for(int j = 0; j < curve->m_points.size()-2; ++j)
210  {
211  NodeSharedPtr n(new Node(j, (*curve->m_points[j+1])(0),
212  (*curve->m_points[j+1])(1),
213  (*curve->m_points[j+1])(2)));
214  edg->m_edgeNodes.push_back(n);
215  }
216  }
217 
218  // Curved Faces
219  SpatialDomains::CurveMap &curvedFaces = graph->GetCurvedFaces();
220  for (it = curvedFaces.begin(); it != curvedFaces.end(); ++it)
221  {
222  SpatialDomains::CurveSharedPtr curve = it->second;
223  int id = curve->m_curveID;
224  ASSERTL1(fIdMap.find(id) != fIdMap.end(),
225  "Failed to find curved edge");
226  FaceSharedPtr fac = fIdMap[id];
227  fac->m_curveType = curve->m_ptype;
228  int Ntot = curve->m_points.size();
229 
230  if (fac->m_curveType == LibUtilities::eNodalTriFekete ||
231  fac->m_curveType == LibUtilities::eNodalTriEvenlySpaced ||
232  fac->m_curveType == LibUtilities::eNodalTriElec)
233  {
234  int N = ((int)sqrt(8.0*Ntot+1.0)-1)/2;
235  for(int j = 3+3*(N-2); j < Ntot; ++j)
236  {
237  NodeSharedPtr n(new Node(j, (*curve->m_points[j])(0),
238  (*curve->m_points[j])(1),
239  (*curve->m_points[j])(2)));
240  fac->m_faceNodes.push_back(n);
241  }
242  }
243  else // quad face.
244  {
245  int N = (int)sqrt((double)Ntot);
246  for(int j = 1; j < N-1; ++j)
247  {
248  for(int k = 1; k < N-1; ++k)
249  {
250  NodeSharedPtr n(new Node((j-1)*(N-2)+k-1,
251  (*curve->m_points[j*N+k])(0),
252  (*curve->m_points[j*N+k])(1),
253  (*curve->m_points[j*N+k])(2)));
254  fac->m_faceNodes.push_back(n);
255  }
256  }
257  }
258  }
259 
260  // Get hold of mesh composites and set up m_mesh->m_elements
261 
262  SpatialDomains::CompositeMap GraphComps= graph->GetComposites();
265 
266 
267  // calculate the number of element of dimension
268  // m_mesh->m_expDim in composite list so we can set up
269  // element vector of this size to allow for
270  // non-consecutive insertion to list (Might consider
271  // setting element up as a map)?
272  int nel = 0;
273  for(compIt = GraphComps.begin(); compIt != GraphComps.end(); ++compIt)
274  {
275  // Get hold of dimension
276  int dim = (*compIt->second)[0]->GetShapeDim();
277 
278  if(dim == m_mesh->m_expDim)
279  {
280  nel += (*compIt->second).size();
281  }
282  }
283  m_mesh->m_element[m_mesh->m_expDim].resize(nel);
284 
285  // loop over all composites and set up elements with edges and faces from the maps above.
286  for(compIt = GraphComps.begin(); compIt != GraphComps.end(); ++compIt)
287  {
288  // Get hold of dimension
289  int dim = (*compIt->second)[0]->GetShapeDim();
290 
291  // compIt->second is a GeometryVector
292  for(geomIt = (*compIt->second).begin();
293  geomIt != (*compIt->second).end();
294  ++geomIt)
295  {
296  ElmtConfig conf((*geomIt)->GetShapeType(),1,true,true);
297 
298  // Get hold of geometry
299  vector<NodeSharedPtr> nodeList;
300  for (int i = 0; i < (*geomIt)->GetNumVerts(); ++i)
301  {
302  nodeList.push_back(vIdMap[(*geomIt)->GetVid(i)]);
303  }
304 
305  vector<int> tags;
306  tags.push_back(compIt->first);
307 
309  CreateInstance((*geomIt)->GetShapeType(),conf,nodeList,tags);
310 
311  E->SetId((*geomIt)->GetGlobalID());
312 
313  if(dim == m_mesh->m_expDim) // load mesh into location baded on globalID
314  {
315  m_mesh->m_element[dim][(*geomIt)->GetGlobalID()] = E;
316  }
317  else // push onto vector for later usage as composite region
318  {
319  m_mesh->m_element[dim].push_back(E);
320  }
321 
322  if(dim > 1)
323  {
324  // reset edges
325  for (int i = 0; i < (*geomIt)->GetNumEdges(); ++i)
326  {
327  EdgeSharedPtr edg = eIdMap[(*geomIt)->GetEid(i)];
328  E->SetEdge(i,edg);
329  // set up link back to this element
330  edg->m_elLink.push_back(pair<ElementSharedPtr,int>(E,i));
331  }
332  }
333 
334  if(dim == 3)
335  {
336  // reset faces
337  for (int i = 0; i < (*geomIt)->GetNumFaces(); ++i)
338  {
339  FaceSharedPtr fac = fIdMap[(*geomIt)->GetFid(i)];
340  E->SetFace(i,fac);
341  // set up link back to this slement
342  fac->m_elLink.push_back(pair<ElementSharedPtr,int>(E,i));
343  }
344  }
345  }
346  }
347  ProcessEdges(false);
348  ProcessFaces(false);
350  }
351  }
352 }
pair< ModuleType, string > ModuleKey
Base class for shape geometry information.
Definition: Geometry.h:76
static boost::shared_ptr< MeshGraph > Read(const LibUtilities::SessionReaderSharedPtr &pSession, DomainRangeShPtr &rng=NullDomainRangeShPtr)
Definition: MeshGraph.cpp:119
Represents an edge which joins two points.
Definition: MeshElements.h:227
boost::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
Definition: MeshElements.h:318
map< string, ConfigOption > m_config
List of configuration values.
STL namespace.
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
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:50
boost::shared_ptr< Curve > CurveSharedPtr
Definition: Curve.hpp:62
virtual void ProcessEdges(bool ReprocessEdges=true)
Extract element edges.
boost::shared_ptr< Element > ElementSharedPtr
Shared pointer to an element.
Definition: MeshElements.h:63
std::vector< GeometrySharedPtr >::iterator GeometryVectorIter
Definition: Geometry.h:58
std::map< int, TriGeomSharedPtr > TriGeomMap
Definition: TriGeom.h:62
1D Evenly-spaced points using Lagrange polynomial
Definition: PointsType.h:63
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
std::map< int, SegGeomSharedPtr > SegGeomMap
Definition: SegGeom.h:54
std::map< int, Composite >::iterator CompositeMapIter
Definition: MeshGraph.h:113
boost::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
Basic information about an element.
Definition: MeshElements.h:583
virtual void ProcessComposites()
Generate composites.
Represents a point in the domain.
Definition: MeshElements.h:74
std::map< int, Composite > CompositeMap
Definition: MeshGraph.h:112
2D Nodal Fekete Points on a Triangle
Definition: PointsType.h:69
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
std::map< int, QuadGeomSharedPtr > QuadGeomMap
Definition: QuadGeom.h:57
virtual void ProcessFaces(bool ReprocessFaces=true)
Extract element faces.
boost::unordered_map< int, CurveSharedPtr > CurveMap
Definition: Curve.hpp:63
2D Evenly-spaced points on a Triangle
Definition: PointsType.h:70
Represents a face comprised of three or more edges.
Definition: MeshElements.h:352
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:191
boost::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:432
ElementFactory & GetElementFactory()
boost::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:60
2D Nodal Electrostatic Points on a Triangle
Definition: PointsType.h:68
ModuleFactory & GetModuleFactory()
Abstract base class for input modules.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:215