Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
EnsiteToXml.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <fstream>
3 #include <iomanip>
4 #include <sstream>
5 #include <vector>
6 #include <list>
7 
8 #include <tinyxml.h>
9 using namespace std;
10 
11 
12 struct Vertex
13 {
14  Vertex(int id, double x, double y, double z):
15 id(id),
16 x(x),
17 y(y),
18 z(z)
19  {};
20  int id;
21  double x;
22  double y;
23  double z;
24 };
25 
26 struct Edge
27 {
28  Edge(int id, vector<int> vert):
29 id(id),
30 vert(vert)
31  {};
32  int id;
33  vector<int> vert;
34 };
35 
37 {
38  TwoDElement(int id, int type, vector<int> tags, vector<int> vert, vector<int> edge):
39 id(id),
40 type(type),
41 tags(tags),
42 verts(vert),
43 edges(edge)
44  {};
45  TwoDElement(int id, int type, vector<int> vert):
46  id(id),
47  type(type),
48  verts(vert)
49  {};
50  int id;
51  int type;
52  vector<int> tags;
53  vector<int> verts;
54  vector<int> edges;
55 };
56 
57 void readEnsite(const char* filename,
58  vector<Vertex>& pVertexList,
59  vector<TwoDElement>& pElementList)
60 {
61  cout << "Reading Ensite file..." << flush;
62  TiXmlDocument vEnsite(filename);
63  TiXmlElement * vElmt;
64  stringstream vTmp;
65  int n;
66 
67  if (!vEnsite.LoadFile()) {
68  cout << "Unable to open file " << filename << endl;
69  exit(-1);
70  }
71 
72  vElmt = vEnsite.FirstChildElement("DIF");
73  if (!vElmt) cout << "Unable to find DIF tag" << endl;
74  vElmt = vElmt->FirstChildElement("DIFBody");
75  if (!vElmt) cout << "Unable to find DIFBody tag" << endl;
76  vElmt = vElmt->FirstChildElement("Volumes");
77  if (!vElmt) cout << "Unable to find Volumes tag" << endl;
78  vElmt = vElmt->FirstChildElement("Volume");
79  if (!vElmt) cout << "Unable to find Volume tag" << endl;
80 
81  TiXmlElement * vVertices = vElmt->FirstChildElement("Vertices");
82  if (!vVertices) cout << "Unable to find Vertices tag" << endl;
83  int vNVertices = atoi(vVertices->Attribute("number"));
84  TiXmlElement * vPolygons = vElmt->FirstChildElement("Polygons");
85  if (!vPolygons) cout << "Unable to find Polygons tag" << endl;
86  int vNPolygons = atoi(vPolygons->Attribute("number"));
87 
88  // Read vertices
89  vTmp.write(vVertices->GetText(), strlen(vVertices->GetText()));
90  double x, y, z;
91  for (n = 0; n < vNVertices; ++n)
92  {
93  vTmp >> x >> y >> z;
94  pVertexList.push_back(Vertex(n,x,y,z));
95  }
96 
97  // Read polygons
98  vTmp.clear();
99  vTmp.write(vPolygons->GetText(), strlen(vPolygons->GetText()));
100  int a, b, c;
101  for (n = 0; n < vNPolygons; ++n)
102  {
103  vTmp >> a >> b >> c;
104  vector<int> vert;
105  vert.push_back(a-1);
106  vert.push_back(b-1);
107  vert.push_back(c-1);
108  pElementList.push_back(TwoDElement(n,2,vert));
109  }
110  cout << "done." << endl;
111 }
112 
113 int GetEdge(vector<int> &vert, vector<Edge>& edges, int elm_type)
114 {
115  int i;
116  int size = edges.size();
117  for(i = 0; i < size; i++)
118 {
119  if( ((vert[0] == edges[i].vert[0])&&
120  (vert[1] == edges[i].vert[1]))
121  ||
122  ((vert[1] == edges[i].vert[0])&&
123  (vert[0] == edges[i].vert[1])) )
124  {
125  return i;
126  }
127 }
128 
129  // for the last edge of an element
130  vector<int> edgevert;
131  edgevert.push_back(vert[0]);
132  edgevert.push_back(vert[1]);
133  if(elm_type==9)
134 {
135  edgevert.push_back(vert[2]);
136 }
137  edges.push_back( Edge(size,edgevert) );
138  return size;
139 }
140 
141 void createEdgeList(vector<Vertex>& pVertexList,
142  vector<Edge>& pEdgeList,
143  vector<TwoDElement>& pElementList)
144 {
145  int i,j,edgeid;
146 
147  cout << "Creating edge list..." << flush;
148  for (i = 0; i < pElementList.size(); ++i)
149  {
150  for (j = 0; j < 3; ++j)
151  {
152  vector<int> verts;
153  verts.push_back(pElementList[i].verts[j%3]);
154  verts.push_back(pElementList[i].verts[(j+1)%3]);
155  edgeid = GetEdge(verts, pEdgeList, 2);
156  pElementList[i].edges.push_back(edgeid);
157  }
158  }
159  cout << "done." << endl;
160 }
161 
162 void WriteToXMLFile(const char* outfile, const vector<Vertex> & nodes, const vector<Edge> & edges,
163  const vector<TwoDElement> & twoDElements)
164 {
165  cout << "Writing XML file..." << flush;
166 
167  TiXmlDocument doc;
168  TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "utf-8", "");
169  doc.LinkEndChild( decl );
170 
171  TiXmlElement * root = new TiXmlElement( "NEKTAR" );
172  doc.LinkEndChild( root );
173 
174  //---------------------------------------------
175  // Write DIM and SPACE
176  TiXmlElement * geomTag = new TiXmlElement( "GEOMETRY" );
177  geomTag->SetAttribute("DIM", "2");
178  geomTag->SetAttribute("SPACE", "3");
179  root->LinkEndChild( geomTag );
180  //---------------------------------------------
181 
182  //---------------------------------------------
183  // Write VERTEX
184  TiXmlElement* verTag = new TiXmlElement( "VERTEX" );
185 
186  for( int i = 0; i < nodes.size(); ++i ) {
187  stringstream s;
188  s << scientific << setprecision(3) << nodes[i].x << " "
189  << nodes[i].y << " " << nodes[i].z;
190  TiXmlElement * v = new TiXmlElement( "V" );
191  v->SetAttribute("ID",nodes[i].id);
192  v->LinkEndChild( new TiXmlText(s.str()) );
193  verTag->LinkEndChild(v);
194  }
195  geomTag->LinkEndChild( verTag );
196  //---------------------------------------------
197 
198 
199  //---------------------------------------------
200  // Write EDGE
201  int edgecnt = 0;
202  verTag = new TiXmlElement( "EDGE" );
203 
204  for( int i = 0; i < edges.size(); ++i ) {
205  stringstream s;
206 
207  s << setw(5) << edges[i].vert[0] << " " << edges[i].vert[1] << " ";
208  TiXmlElement * e = new TiXmlElement( "E" );
209  e->SetAttribute("ID",edgecnt++);
210  e->LinkEndChild( new TiXmlText(s.str()) );
211  verTag->LinkEndChild(e);
212  }
213  geomTag->LinkEndChild( verTag );
214  //---------------------------------------------
215 
216 
217  //--------------------------------------------
218  // Write ELEMENT
219  verTag = new TiXmlElement( "ELEMENT" );
220  int elmcnt = 0;
221 
222  for(int i=0; i<twoDElements.size(); ++i){
223  stringstream st;
224  for(int j=0; j<twoDElements[i].edges.size(); ++j){
225  st << setw(5) << twoDElements[i].edges[j] << " ";
226  }
227 
228  TiXmlElement *elm_tag;
229  elm_tag = new TiXmlElement("T");
230  elm_tag->SetAttribute("ID", elmcnt++);
231  elm_tag->LinkEndChild( new TiXmlText(st.str()) );
232  verTag->LinkEndChild(elm_tag);
233  }
234  geomTag->LinkEndChild( verTag );
235  //--------------------------------------------------
236 
237 
238  //--------------------------------------------------
239  // Write COMPOSITE
240  verTag = new TiXmlElement("COMPOSITE");
241 
243  list<int> compList;
244 
245  stringstream st;
246  st << " T[0-" << twoDElements.size()-1 << "]";
247 
248  TiXmlElement *comp_tag = new TiXmlElement("C"); // Composite
249  comp_tag->SetAttribute("ID", "0");
250  comp_tag->LinkEndChild( new TiXmlText(st.str()) );
251  verTag->LinkEndChild(comp_tag);
252  geomTag->LinkEndChild( verTag );
253  //--------------------------------------------------
254 
255  TiXmlElement * domain = new TiXmlElement ("DOMAIN" );
256  domain->LinkEndChild( new TiXmlText( " C[0] " ));
257  geomTag->LinkEndChild( domain );
258 
259  doc.SaveFile(outfile );
260 
261  cout << "done." << endl;
262 } // end of function WriteToXMLFile
263 
264 void WriteMshFile(const char* outfile, const vector<Vertex> & nodes, const vector<Edge> & edges,
265  const vector<TwoDElement> & twoDElements)
266 {
267  cout << "Write GMSH file..." << flush;
268  int n;
269  ofstream out(outfile);
270 
271  out << "$MeshFormat" << endl;
272  out << "2.1 0 8" << endl;
273  out << "$EndMeshFormat" << endl;
274  out << "$Nodes" << endl;
275  out << nodes.size() << endl;
276  for (n = 0; n < nodes.size(); ++n)
277  {
278  out << n+1 << " " << nodes[n].x << " " << nodes[n].y << " "
279  << nodes[n].z << endl;
280  }
281  out << "$EndNodes" << endl;
282  out << "$Elements" << endl;
283  out << twoDElements.size() << endl;
284  for (n = 0; n < twoDElements.size(); ++n)
285  {
286  out << n+1 << " 2 3 1 0 0 " << twoDElements[n].verts[0] + 1 << " "
287  << twoDElements[n].verts[1] + 1
288  << " " << twoDElements[n].verts[2] + 1 << endl;
289  }
290  out << "$EndElements" << endl;
291  cout << "done." << endl;
292 }
293 
294 int main(int argc, char *argv[])
295 {
296  if(argc != 4)
297  {
298  fprintf(stderr,"Usage: EnsiteToXml ensite.xml session.xml mesh.msh\n");
299  exit(1);
300  }
301 
302  vector<Vertex> vVertexList;
303  vector<Edge> vEdgeList;
304  vector<TwoDElement> vElementList;
305 
306  readEnsite(argv[1], vVertexList, vElementList);
307  createEdgeList(vVertexList, vEdgeList, vElementList);
308  WriteToXMLFile(argv[2], vVertexList, vEdgeList, vElementList);
309  WriteMshFile(argv[3], vVertexList, vEdgeList, vElementList);
310 }