Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
OutputNekpp.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: OutputNekpp.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: Nektar++ file format output.
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 #include <set>
37 #include <string>
38 using namespace std;
39 
40 #include <boost/iostreams/filtering_streambuf.hpp>
41 #include <boost/iostreams/copy.hpp>
42 #include <boost/iostreams/filter/gzip.hpp>
43 namespace io = boost::iostreams;
44 
45 #include <tinyxml.h>
50 
52 #include "OutputNekpp.h"
53 
54 using namespace Nektar::NekMeshUtils;
55 
56 namespace Nektar
57 {
58 namespace Utilities
59 {
60 ModuleKey OutputNekpp::className =
62  OutputNekpp::create,
63  "Writes a Nektar++ xml file.");
64 
65 OutputNekpp::OutputNekpp(MeshSharedPtr m) : OutputModule(m)
66 {
67  m_config["z"] = ConfigOption(
68  true, "0", "Compress output file and append a .gz extension.");
69  m_config["test"] = ConfigOption(
70  true, "0", "Attempt to load resulting mesh and create meshgraph.");
71  m_config["uncompress"] = ConfigOption(true, "0", "Uncompress xml sections");
72  m_config["order"] = ConfigOption(false, "-1", "Enforce a polynomial order");
73 }
74 
76 {
77 }
78 
79 template <typename T> void TestElmts(SpatialDomains::MeshGraphSharedPtr &graph)
80 {
81  const std::map<int, boost::shared_ptr<T> > &tmp =
82  graph->GetAllElementsOfType<T>();
83  typename std::map<int, boost::shared_ptr<T> >::const_iterator it1, it2;
84 
85  SpatialDomains::CurveMap &curvedEdges = graph->GetCurvedEdges();
86  SpatialDomains::CurveMap &curvedFaces = graph->GetCurvedFaces();
87 
88  for (it1 = tmp.begin(), it2 = tmp.end(); it1 != it2; ++it1)
89  {
90  SpatialDomains::GeometrySharedPtr geom = it1->second;
91  geom->FillGeom();
92  geom->Reset(curvedEdges, curvedFaces);
93  }
94 }
95 
97 {
98  if (m_mesh->m_verbose)
99  {
100  cout << "OutputNekpp: Writing file..." << endl;
101  }
102 
103  int order = m_config["order"].as<int>();
104 
105  if (order != -1)
106  {
107  m_mesh->MakeOrder(order, LibUtilities::ePolyEvenlySpaced);
108  }
109 
110  TiXmlDocument doc;
111  TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
112  doc.LinkEndChild(decl);
113 
114  TiXmlElement *root = new TiXmlElement("NEKTAR");
115  doc.LinkEndChild(root);
116 
117  // Begin <GEOMETRY> section
118  TiXmlElement *geomTag = new TiXmlElement("GEOMETRY");
119  geomTag->SetAttribute("DIM", m_mesh->m_expDim);
120  geomTag->SetAttribute("SPACE", m_mesh->m_spaceDim);
121  root->LinkEndChild(geomTag);
122 
123  WriteXmlNodes(geomTag);
124  WriteXmlEdges(geomTag);
125  WriteXmlFaces(geomTag);
126  WriteXmlElements(geomTag);
127  WriteXmlCurves(geomTag);
128  WriteXmlComposites(geomTag);
129  WriteXmlDomain(geomTag);
130  WriteXmlExpansions(root);
131  WriteXmlConditions(root);
132 
133  // Extract the output filename and extension
134  string filename = m_config["outfile"].as<string>();
135 
136  // Compress output and append .gz extension
137  if (m_config["z"].beenSet)
138  {
139  filename += ".gz";
140  ofstream fout(filename.c_str(),
141  std::ios_base::out | std::ios_base::binary);
142 
143  std::stringstream decompressed;
144  decompressed << doc;
145  io::filtering_streambuf<io::output> out;
146  out.push(io::gzip_compressor());
147  out.push(fout);
148  io::copy(decompressed, out);
149 
150  fout.close();
151  }
152  else
153  {
154  doc.SaveFile(filename);
155  }
156 
157  // Test the resulting XML file (with a basic test) by loading it
158  // with the session reader, generating the MeshGraph and testing if
159  // each element is valid.
160  if (m_config["test"].beenSet)
161  {
162  vector<string> filenames(1);
163  filenames[0] = filename;
164 
169 
170  TestElmts<SpatialDomains::SegGeom>(graphShPt);
171  TestElmts<SpatialDomains::TriGeom>(graphShPt);
172  TestElmts<SpatialDomains::QuadGeom>(graphShPt);
173  TestElmts<SpatialDomains::TetGeom>(graphShPt);
174  TestElmts<SpatialDomains::PrismGeom>(graphShPt);
175  TestElmts<SpatialDomains::PyrGeom>(graphShPt);
176  TestElmts<SpatialDomains::HexGeom>(graphShPt);
177  }
178 }
179 
180 void OutputNekpp::WriteXmlNodes(TiXmlElement *pRoot)
181 {
182  bool UnCompressed = m_config["uncompress"].beenSet;
183 
184  TiXmlElement *verTag = new TiXmlElement("VERTEX");
186 
187  std::set<NodeSharedPtr> tmp(m_mesh->m_vertexSet.begin(),
188  m_mesh->m_vertexSet.end());
189 
190  if (UnCompressed)
191  {
192  for (it = tmp.begin(); it != tmp.end(); ++it)
193  {
194  NodeSharedPtr n = *it;
195  stringstream s;
196  s << scientific << setprecision(8) << n->m_x << " " << n->m_y << " "
197  << n->m_z;
198  TiXmlElement *v = new TiXmlElement("V");
199  v->SetAttribute("ID", n->m_id);
200  v->LinkEndChild(new TiXmlText(s.str()));
201  verTag->LinkEndChild(v);
202  }
203  }
204  else
205  {
206  std::vector<LibUtilities::MeshVertex> vertInfo;
207  for (it = tmp.begin(); it != tmp.end(); ++it)
208  {
210  NodeSharedPtr n = *it;
211  v.id = n->m_id;
212  v.x = n->m_x;
213  v.y = n->m_y;
214  v.z = n->m_z;
215  vertInfo.push_back(v);
216  }
217  std::string vertStr;
219  verTag->SetAttribute("COMPRESSED",
221  verTag->SetAttribute("BITSIZE",
223 
224  verTag->LinkEndChild(new TiXmlText(vertStr));
225  }
226 
227  pRoot->LinkEndChild(verTag);
228 }
229 
230 void OutputNekpp::WriteXmlEdges(TiXmlElement *pRoot)
231 {
232  bool UnCompressed = m_config["uncompress"].beenSet;
233 
234  if (m_mesh->m_expDim >= 2)
235  {
236  TiXmlElement *verTag = new TiXmlElement("EDGE");
237 
239  std::set<EdgeSharedPtr> tmp(m_mesh->m_edgeSet.begin(),
240  m_mesh->m_edgeSet.end());
241  if (UnCompressed)
242  {
243  for (it = tmp.begin(); it != tmp.end(); ++it)
244  {
245  EdgeSharedPtr ed = *it;
246  stringstream s;
247 
248  s << setw(5) << ed->m_n1->m_id << " " << ed->m_n2->m_id
249  << " ";
250  TiXmlElement *e = new TiXmlElement("E");
251  e->SetAttribute("ID", ed->m_id);
252  e->LinkEndChild(new TiXmlText(s.str()));
253  verTag->LinkEndChild(e);
254  }
255  }
256  else
257  {
258  std::vector<LibUtilities::MeshEdge> edgeInfo;
259  for (it = tmp.begin(); it != tmp.end(); ++it)
260  {
262  EdgeSharedPtr ed = *it;
263 
264  e.id = ed->m_id;
265  e.v0 = ed->m_n1->m_id;
266  e.v1 = ed->m_n2->m_id;
267 
268  edgeInfo.push_back(e);
269  }
270  std::string edgeStr;
272  edgeStr);
273  verTag->SetAttribute(
275  verTag->SetAttribute("BITSIZE",
277  verTag->LinkEndChild(new TiXmlText(edgeStr));
278  }
279  pRoot->LinkEndChild(verTag);
280  }
281 }
282 
283 void OutputNekpp::WriteXmlFaces(TiXmlElement *pRoot)
284 {
285  bool UnCompressed = m_config["uncompress"].beenSet;
286 
287  if (m_mesh->m_expDim == 3)
288  {
289  TiXmlElement *verTag = new TiXmlElement("FACE");
291  std::set<FaceSharedPtr> tmp(m_mesh->m_faceSet.begin(),
292  m_mesh->m_faceSet.end());
293 
294  if (UnCompressed)
295  {
296  for (it = tmp.begin(); it != tmp.end(); ++it)
297  {
298  stringstream s;
299  FaceSharedPtr fa = *it;
300 
301  for (int j = 0; j < fa->m_edgeList.size(); ++j)
302  {
303  s << setw(10) << fa->m_edgeList[j]->m_id;
304  }
305  TiXmlElement *f;
306  switch (fa->m_vertexList.size())
307  {
308  case 3:
309  f = new TiXmlElement("T");
310  break;
311  case 4:
312  f = new TiXmlElement("Q");
313  break;
314  default:
315  abort();
316  }
317  f->SetAttribute("ID", fa->m_id);
318  f->LinkEndChild(new TiXmlText(s.str()));
319  verTag->LinkEndChild(f);
320  }
321  }
322  else
323  {
324  std::vector<LibUtilities::MeshTri> TriFaceInfo;
325  std::vector<LibUtilities::MeshQuad> QuadFaceInfo;
326 
327  for (it = tmp.begin(); it != tmp.end(); ++it)
328  {
329  FaceSharedPtr fa = *it;
330 
331  switch (fa->m_edgeList.size())
332  {
333  case 3:
334  {
336  f.id = fa->m_id;
337  for (int i = 0; i < 3; ++i)
338  {
339  f.e[i] = fa->m_edgeList[i]->m_id;
340  }
341  TriFaceInfo.push_back(f);
342  }
343  break;
344  case 4:
345  {
347  f.id = fa->m_id;
348  for (int i = 0; i < 4; ++i)
349  {
350  f.e[i] = fa->m_edgeList[i]->m_id;
351  }
352  QuadFaceInfo.push_back(f);
353  }
354  break;
355  default:
356  ASSERTL0(false, "Unkonwn face type");
357  }
358  }
359 
360  if (TriFaceInfo.size())
361  {
362  std::string vType("T");
363  TiXmlElement *x = new TiXmlElement(vType);
364  std::string faceStr;
366  faceStr);
367  x->SetAttribute(
368  "COMPRESSED",
370  x->SetAttribute("BITSIZE",
372  x->LinkEndChild(new TiXmlText(faceStr));
373  verTag->LinkEndChild(x);
374  }
375 
376  if (QuadFaceInfo.size())
377  {
378  std::string vType("Q");
379  TiXmlElement *x = new TiXmlElement(vType);
380  std::string faceStr;
382  faceStr);
383  x->SetAttribute(
384  "COMPRESSED",
386  x->SetAttribute("BITSIZE",
388  x->LinkEndChild(new TiXmlText(faceStr));
389  verTag->LinkEndChild(x);
390  }
391  }
392  pRoot->LinkEndChild(verTag);
393  }
394 }
395 
396 void OutputNekpp::WriteXmlElements(TiXmlElement *pRoot)
397 {
398  bool UnCompressed = m_config["uncompress"].beenSet;
399 
400  TiXmlElement *verTag = new TiXmlElement("ELEMENT");
401  vector<ElementSharedPtr> &elmt = m_mesh->m_element[m_mesh->m_expDim];
402 
403  if (UnCompressed)
404  {
405  for (int i = 0; i < elmt.size(); ++i)
406  {
407  TiXmlElement *elm_tag = new TiXmlElement(elmt[i]->GetTag());
408  elm_tag->SetAttribute("ID", elmt[i]->GetId());
409  elm_tag->LinkEndChild(new TiXmlText(elmt[i]->GetXmlString()));
410  verTag->LinkEndChild(elm_tag);
411  }
412  }
413  else
414  {
415  std::vector<LibUtilities::MeshEdge> SegInfo;
416  std::vector<LibUtilities::MeshTri> TriInfo;
417  std::vector<LibUtilities::MeshQuad> QuadInfo;
418  std::vector<LibUtilities::MeshTet> TetInfo;
419  std::vector<LibUtilities::MeshPyr> PyrInfo;
420  std::vector<LibUtilities::MeshPrism> PrismInfo;
421  std::vector<LibUtilities::MeshHex> HexInfo;
422 
423  for (int i = 0; i < elmt.size(); ++i)
424  {
425  switch (elmt[i]->GetTag()[0])
426  {
427  case 'S':
428  {
430  e.id = elmt[i]->GetId();
431  e.v0 = elmt[i]->GetVertex(0)->m_id;
432  e.v1 = elmt[i]->GetVertex(1)->m_id;
433  SegInfo.push_back(e);
434  }
435  break;
436  case 'T':
437  {
439  e.id = elmt[i]->GetId();
440  for (int j = 0; j < 3; ++j)
441  {
442  e.e[j] = elmt[i]->GetEdge(j)->m_id;
443  }
444  TriInfo.push_back(e);
445  }
446  break;
447  case 'Q':
448  {
450  e.id = elmt[i]->GetId();
451  for (int j = 0; j < 4; ++j)
452  {
453  e.e[j] = elmt[i]->GetEdge(j)->m_id;
454  }
455  QuadInfo.push_back(e);
456  }
457  break;
458  case 'A':
459  {
461  e.id = elmt[i]->GetId();
462  for (int j = 0; j < 4; ++j)
463  {
464  e.f[j] = elmt[i]->GetFace(j)->m_id;
465  }
466  TetInfo.push_back(e);
467  }
468  break;
469  case 'P':
470  {
472  e.id = elmt[i]->GetId();
473  for (int j = 0; j < 5; ++j)
474  {
475  e.f[j] = elmt[i]->GetFace(j)->m_id;
476  }
477  PyrInfo.push_back(e);
478  }
479  break;
480  case 'R':
481  {
483  e.id = elmt[i]->GetId();
484  for (int j = 0; j < 5; ++j)
485  {
486  e.f[j] = elmt[i]->GetFace(j)->m_id;
487  }
488  PrismInfo.push_back(e);
489  }
490  break;
491  case 'H':
492  {
494  e.id = elmt[i]->GetId();
495  for (int j = 0; j < 6; ++j)
496  {
497  e.f[j] = elmt[i]->GetFace(j)->m_id;
498  }
499  HexInfo.push_back(e);
500  }
501  break;
502  default:
503  ASSERTL0(false, "Unknown element type");
504  }
505  }
506 
507  if (SegInfo.size())
508  {
509  std::string vType("S");
510  TiXmlElement *x = new TiXmlElement(vType);
511  std::string Str;
513  x->SetAttribute("COMPRESSED",
515  x->SetAttribute("BITSIZE",
517  x->LinkEndChild(new TiXmlText(Str));
518  verTag->LinkEndChild(x);
519  }
520 
521  if (TriInfo.size())
522  {
523  std::string vType("T");
524  TiXmlElement *x = new TiXmlElement(vType);
525  std::string Str;
527  x->SetAttribute("COMPRESSED",
529  x->SetAttribute("BITSIZE",
531  x->LinkEndChild(new TiXmlText(Str));
532  verTag->LinkEndChild(x);
533  }
534 
535  if (QuadInfo.size())
536  {
537  std::string vType("Q");
538  TiXmlElement *x = new TiXmlElement(vType);
539  std::string Str;
541  x->SetAttribute("COMPRESSED",
543  x->SetAttribute("BITSIZE",
545  x->LinkEndChild(new TiXmlText(Str));
546  verTag->LinkEndChild(x);
547  }
548 
549  if (TetInfo.size())
550  {
551  std::string vType("A");
552  TiXmlElement *x = new TiXmlElement(vType);
553  std::string Str;
555  x->SetAttribute("COMPRESSED",
557  x->SetAttribute("BITSIZE",
559  x->LinkEndChild(new TiXmlText(Str));
560  verTag->LinkEndChild(x);
561  }
562 
563  if (PyrInfo.size())
564  {
565  std::string vType("P");
566  TiXmlElement *x = new TiXmlElement(vType);
567  std::string Str;
569  x->SetAttribute("COMPRESSED",
571  x->SetAttribute("BITSIZE",
573  x->LinkEndChild(new TiXmlText(Str));
574  verTag->LinkEndChild(x);
575  }
576 
577  if (PrismInfo.size())
578  {
579  std::string vType("R");
580  TiXmlElement *x = new TiXmlElement(vType);
581  std::string Str;
583  x->SetAttribute("COMPRESSED",
585  x->SetAttribute("BITSIZE",
587  x->LinkEndChild(new TiXmlText(Str));
588  verTag->LinkEndChild(x);
589  }
590 
591  if (HexInfo.size())
592  {
593  std::string vType("H");
594  TiXmlElement *x = new TiXmlElement(vType);
595  std::string Str;
597  x->SetAttribute("COMPRESSED",
599  x->SetAttribute("BITSIZE",
601  x->LinkEndChild(new TiXmlText(Str));
602  verTag->LinkEndChild(x);
603  }
604  }
605 
606  pRoot->LinkEndChild(verTag);
607 }
608 
609 void OutputNekpp::WriteXmlCurves(TiXmlElement *pRoot)
610 {
611  bool UnCompressed = m_config["uncompress"].beenSet;
612 
613  int edgecnt = 0;
614 
615  bool curve = false;
617  if (m_mesh->m_expDim > 1)
618  {
619  for (it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end();
620  ++it)
621  {
622  if ((*it)->m_edgeNodes.size() > 0)
623  {
624  curve = true;
625  break;
626  }
627  }
628  }
629  else if (m_mesh->m_expDim == 1)
630  {
631  for (int i = 0; i < m_mesh->m_element[1].size(); ++i)
632  {
633  if (m_mesh->m_element[1][i]->GetVolumeNodes().size() > 0)
634  {
635  curve = true;
636  break;
637  }
638  }
639  }
640  if (!curve)
641  return;
642 
643  TiXmlElement *curved = new TiXmlElement("CURVED");
644 
645  if (UnCompressed)
646  {
647  for (it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end();
648  ++it)
649  {
650  if ((*it)->m_edgeNodes.size() > 0)
651  {
652  TiXmlElement *e = new TiXmlElement("E");
653  e->SetAttribute("ID", edgecnt++);
654  e->SetAttribute("EDGEID", (*it)->m_id);
655  e->SetAttribute("NUMPOINTS", (*it)->GetNodeCount());
656  e->SetAttribute(
657  "TYPE", LibUtilities::kPointsTypeStr[(*it)->m_curveType]);
658  TiXmlText *t0 = new TiXmlText((*it)->GetXmlCurveString());
659  e->LinkEndChild(t0);
660  curved->LinkEndChild(e);
661  }
662  }
663 
664  int facecnt = 0;
665 
666  if (m_mesh->m_expDim == 1 && m_mesh->m_spaceDim > 1)
667  {
669  for (it = m_mesh->m_element[m_mesh->m_expDim].begin();
670  it != m_mesh->m_element[m_mesh->m_expDim].end();
671  ++it)
672  {
673  // Only generate face curve if there are volume nodes
674  if ((*it)->GetVolumeNodes().size() > 0)
675  {
676  TiXmlElement *e = new TiXmlElement("E");
677  e->SetAttribute("ID", facecnt++);
678  e->SetAttribute("EDGEID", (*it)->GetId());
679  e->SetAttribute("NUMPOINTS", (*it)->GetNodeCount());
680  e->SetAttribute(
681  "TYPE",
682  LibUtilities::kPointsTypeStr[(*it)->GetCurveType()]);
683 
684  TiXmlText *t0 = new TiXmlText((*it)->GetXmlCurveString());
685  e->LinkEndChild(t0);
686  curved->LinkEndChild(e);
687  }
688  }
689  }
690  // 2D elements in 3-space, output face curvature information
691  else if (m_mesh->m_expDim == 2 &&
692  m_mesh->m_spaceDim >= 2)
693  {
695  for (it = m_mesh->m_element[m_mesh->m_expDim].begin();
696  it != m_mesh->m_element[m_mesh->m_expDim].end();
697  ++it)
698  {
699  // Only generate face curve if there are volume nodes
700  if ((*it)->GetVolumeNodes().size() > 0)
701  {
702  TiXmlElement *e = new TiXmlElement("F");
703  e->SetAttribute("ID", facecnt++);
704  e->SetAttribute("FACEID", (*it)->GetId());
705  e->SetAttribute("NUMPOINTS", (*it)->GetNodeCount());
706  e->SetAttribute(
707  "TYPE",
708  LibUtilities::kPointsTypeStr[(*it)->GetCurveType()]);
709 
710  TiXmlText *t0 = new TiXmlText((*it)->GetXmlCurveString());
711  e->LinkEndChild(t0);
712  curved->LinkEndChild(e);
713  }
714  }
715  }
716  else if (m_mesh->m_expDim == 3)
717  {
718  FaceSet::iterator it2;
719  for (it2 = m_mesh->m_faceSet.begin();
720  it2 != m_mesh->m_faceSet.end();
721  ++it2)
722  {
723  if ((*it2)->m_faceNodes.size() > 0)
724  {
725  TiXmlElement *f = new TiXmlElement("F");
726  f->SetAttribute("ID", facecnt++);
727  f->SetAttribute("FACEID", (*it2)->m_id);
728  f->SetAttribute("NUMPOINTS", (*it2)->GetNodeCount());
729  f->SetAttribute(
730  "TYPE",
731  LibUtilities::kPointsTypeStr[(*it2)->m_curveType]);
732  TiXmlText *t0 = new TiXmlText((*it2)->GetXmlCurveString());
733  f->LinkEndChild(t0);
734  curved->LinkEndChild(f);
735  }
736  }
737  }
738  }
739  else
740  {
741  std::vector<LibUtilities::MeshCurvedInfo> edgeinfo;
742  std::vector<LibUtilities::MeshCurvedInfo> faceinfo;
743  LibUtilities::MeshCurvedPts curvedpts;
744  curvedpts.id = 0; // assume all points are going in here
745  int ptoffset = 0;
746  int newidx = 0;
747  NodeSet cvertlist;
748 
749  for (it = m_mesh->m_edgeSet.begin(); it != m_mesh->m_edgeSet.end();
750  ++it)
751  {
752  if ((*it)->m_edgeNodes.size() > 0)
753  {
755  cinfo.id = edgecnt++;
756  cinfo.entityid = (*it)->m_id;
757  cinfo.npoints = (*it)->m_edgeNodes.size() + 2;
758  cinfo.ptype = (*it)->m_curveType;
759  cinfo.ptid = 0; // set to just one point set
760  cinfo.ptoffset = ptoffset;
761 
762  edgeinfo.push_back(cinfo);
763 
764  std::vector<NodeSharedPtr> nodeList;
765  (*it)->GetCurvedNodes(nodeList);
766 
767  // fill in points
768  for (int i = 0; i < nodeList.size(); ++i)
769  {
770  pair<NodeSet::iterator, bool> testIns =
771  cvertlist.insert(nodeList[i]);
772 
773  if (testIns.second) // have inserted node
774  {
775  (*(testIns.first))->m_id = newidx;
776 
778  v.id = newidx;
779  v.x = nodeList[i]->m_x;
780  v.y = nodeList[i]->m_y;
781  v.z = nodeList[i]->m_z;
782  curvedpts.pts.push_back(v);
783  newidx++;
784  }
785 
786  curvedpts.index.push_back((*(testIns.first))->m_id);
787  }
788 
789  ptoffset += cinfo.npoints;
790  }
791  }
792 
793  int facecnt = 0;
794 
795  // 1D element in 2 or 3 space
796  if (m_mesh->m_expDim == 1 && m_mesh->m_spaceDim > 1)
797  {
799  for (it = m_mesh->m_element[m_mesh->m_expDim].begin();
800  it != m_mesh->m_element[m_mesh->m_expDim].end();
801  ++it)
802  {
803  // Only generate face curve if there are volume nodes
804  if ((*it)->GetVolumeNodes().size() > 0)
805  {
807  cinfo.id = facecnt++;
808  cinfo.entityid = (*it)->GetId();
809  cinfo.npoints = (*it)->GetNodeCount();
810  cinfo.ptype = (*it)->GetCurveType();
811  cinfo.ptid = 0; // set to just one point set
812  cinfo.ptoffset = ptoffset;
813 
814  edgeinfo.push_back(cinfo);
815 
816  // fill in points
817  vector<NodeSharedPtr> tmp;
818  (*it)->GetCurvedNodes(tmp);
819 
820  for (int i = 0; i < tmp.size(); ++i)
821  {
822  pair<NodeSet::iterator, bool> testIns =
823  cvertlist.insert(tmp[i]);
824 
825  if (testIns.second) // have inserted node
826  {
827  (*(testIns.first))->m_id = newidx;
828 
830  v.id = newidx;
831  v.x = tmp[i]->m_x;
832  v.y = tmp[i]->m_y;
833  v.z = tmp[i]->m_z;
834  curvedpts.pts.push_back(v);
835  newidx++;
836  }
837  curvedpts.index.push_back((*(testIns.first))->m_id);
838  }
839  ptoffset += cinfo.npoints;
840  }
841  }
842  }
843  // 2D elements in 3-space, output face curvature information
844  else if (m_mesh->m_expDim == 2 && m_mesh->m_spaceDim == 3)
845  {
847  for (it = m_mesh->m_element[m_mesh->m_expDim].begin();
848  it != m_mesh->m_element[m_mesh->m_expDim].end();
849  ++it)
850  {
851  // Only generate face curve if there are volume nodes
852  if ((*it)->GetVolumeNodes().size() > 0)
853  {
855  cinfo.id = facecnt++;
856  cinfo.entityid = (*it)->GetId();
857  cinfo.npoints = (*it)->GetNodeCount();
858  cinfo.ptype = (*it)->GetCurveType();
859  cinfo.ptid = 0; // set to just one point set
860  cinfo.ptoffset = ptoffset;
861 
862  faceinfo.push_back(cinfo);
863 
864  // fill in points
865  vector<NodeSharedPtr> tmp;
866  (*it)->GetCurvedNodes(tmp);
867 
868  for (int i = 0; i < tmp.size(); ++i)
869  {
870  pair<NodeSet::iterator, bool> testIns =
871  cvertlist.insert(tmp[i]);
872 
873  if (testIns.second) // have inserted node
874  {
875  (*(testIns.first))->m_id = newidx;
876 
878  v.id = newidx;
879  v.x = tmp[i]->m_x;
880  v.y = tmp[i]->m_y;
881  v.z = tmp[i]->m_z;
882  curvedpts.pts.push_back(v);
883  newidx++;
884  }
885  curvedpts.index.push_back((*(testIns.first))->m_id);
886  }
887  ptoffset += cinfo.npoints;
888  }
889  }
890  }
891  else if (m_mesh->m_expDim == 3)
892  {
893  FaceSet::iterator it2;
894  for (it2 = m_mesh->m_faceSet.begin();
895  it2 != m_mesh->m_faceSet.end();
896  ++it2)
897  {
898  if ((*it2)->m_faceNodes.size() > 0)
899  {
900  vector<NodeSharedPtr> tmp;
901  (*it2)->GetCurvedNodes(tmp);
902 
904  cinfo.id = facecnt++;
905  cinfo.entityid = (*it2)->m_id;
906  cinfo.npoints = tmp.size();
907  cinfo.ptype = (*it2)->m_curveType;
908  cinfo.ptid = 0; // set to just one point set
909  cinfo.ptoffset = ptoffset;
910 
911  faceinfo.push_back(cinfo);
912 
913  for (int i = 0; i < tmp.size(); ++i)
914  {
915  pair<NodeSet::iterator, bool> testIns =
916  cvertlist.insert(tmp[i]);
917 
918  if (testIns.second) // have inserted node
919  {
920  (*(testIns.first))->m_id = newidx;
921 
923  v.id = newidx;
924  v.x = tmp[i]->m_x;
925  v.y = tmp[i]->m_y;
926  v.z = tmp[i]->m_z;
927  curvedpts.pts.push_back(v);
928  newidx++;
929  }
930  curvedpts.index.push_back((*(testIns.first))->m_id);
931  }
932  ptoffset += cinfo.npoints;
933  }
934  }
935  }
936 
937  // add xml information
938  if (edgeinfo.size())
939  {
940  curved->SetAttribute(
942  curved->SetAttribute("BITSIZE",
944 
945  TiXmlElement *x = new TiXmlElement("E");
946  std::string dataStr;
948  dataStr);
949  x->LinkEndChild(new TiXmlText(dataStr));
950  curved->LinkEndChild(x);
951  }
952 
953  if (faceinfo.size())
954  {
955  curved->SetAttribute(
957  curved->SetAttribute("BITSIZE",
959 
960  TiXmlElement *x = new TiXmlElement("F");
961  std::string dataStr;
963  dataStr);
964  x->LinkEndChild(new TiXmlText(dataStr));
965  curved->LinkEndChild(x);
966  }
967 
968  if (edgeinfo.size() || faceinfo.size())
969  {
970  TiXmlElement *x = new TiXmlElement("DATAPOINTS");
971  x->SetAttribute("ID", curvedpts.id);
972 
973  TiXmlElement *subx = new TiXmlElement("INDEX");
974  std::string dataStr;
976  dataStr);
977  subx->LinkEndChild(new TiXmlText(dataStr));
978  x->LinkEndChild(subx);
979 
980  subx = new TiXmlElement("POINTS");
982  dataStr);
983  subx->LinkEndChild(new TiXmlText(dataStr));
984  x->LinkEndChild(subx);
985 
986  curved->LinkEndChild(x);
987  }
988  }
989  pRoot->LinkEndChild(curved);
990 }
991 
992 void OutputNekpp::WriteXmlComposites(TiXmlElement *pRoot)
993 {
994  TiXmlElement *verTag = new TiXmlElement("COMPOSITE");
997  int j = 0;
998 
999  for (it = m_mesh->m_composite.begin(); it != m_mesh->m_composite.end();
1000  ++it, ++j)
1001  {
1002  if (it->second->m_items.size() > 0)
1003  {
1004  TiXmlElement *comp_tag = new TiXmlElement("C"); // Composite
1005  bool doSort = true;
1006 
1007  // Ensure that this composite is not used for periodic BCs!
1008  for (it2 = m_mesh->m_condition.begin();
1009  it2 != m_mesh->m_condition.end();
1010  ++it2)
1011  {
1012  ConditionSharedPtr c = it2->second;
1013 
1014  // Ignore non-periodic boundary conditions.
1015  if (find(c->type.begin(), c->type.end(), ePeriodic) ==
1016  c->type.end())
1017  {
1018  continue;
1019  }
1020 
1021  for (int i = 0; i < c->m_composite.size(); ++i)
1022  {
1023  if (c->m_composite[i] == j)
1024  {
1025  doSort = false;
1026  }
1027  }
1028  }
1029 
1030  doSort = doSort && it->second->m_reorder;
1031  comp_tag->SetAttribute("ID", it->second->m_id);
1032  if (it->second->m_label.size())
1033  {
1034  comp_tag->SetAttribute("LABEL", it->second->m_label);
1035  }
1036  comp_tag->LinkEndChild(
1037  new TiXmlText(it->second->GetXmlString(doSort)));
1038  verTag->LinkEndChild(comp_tag);
1039  }
1040  else
1041  {
1042  cout << "Composite " << it->second->m_id << " "
1043  << "contains nothing." << endl;
1044  }
1045  }
1046 
1047  pRoot->LinkEndChild(verTag);
1048 }
1049 
1050 void OutputNekpp::WriteXmlDomain(TiXmlElement *pRoot)
1051 {
1052  // Write the <DOMAIN> subsection.
1053  TiXmlElement *domain = new TiXmlElement("DOMAIN");
1054  std::string list;
1056 
1057  for (it = m_mesh->m_composite.begin(); it != m_mesh->m_composite.end();
1058  ++it)
1059  {
1060  if (it->second->m_items[0]->GetDim() == m_mesh->m_expDim)
1061  {
1062  if (list.length() > 0)
1063  {
1064  list += ",";
1065  }
1066  list += boost::lexical_cast<std::string>(it->second->m_id);
1067  }
1068  }
1069  domain->LinkEndChild(new TiXmlText(" C[" + list + "] "));
1070  pRoot->LinkEndChild(domain);
1071 }
1072 
1073 void OutputNekpp::WriteXmlExpansions(TiXmlElement *pRoot)
1074 {
1075  // Write a default <EXPANSIONS> section.
1076  TiXmlElement *expansions = new TiXmlElement("EXPANSIONS");
1078 
1079  for (it = m_mesh->m_composite.begin(); it != m_mesh->m_composite.end();
1080  ++it)
1081  {
1082  if (it->second->m_items[0]->GetDim() == m_mesh->m_expDim)
1083  {
1084  TiXmlElement *exp = new TiXmlElement("E");
1085  exp->SetAttribute(
1086  "COMPOSITE",
1087  "C[" + boost::lexical_cast<std::string>(it->second->m_id) +
1088  "]");
1089  exp->SetAttribute("NUMMODES", 4);
1090  exp->SetAttribute("TYPE", "MODIFIED");
1091 
1092  if (m_mesh->m_fields.size() == 0)
1093  {
1094  exp->SetAttribute("FIELDS", "u");
1095  }
1096  else
1097  {
1098  string fstr;
1099  for (int i = 0; i < m_mesh->m_fields.size(); ++i)
1100  {
1101  fstr += m_mesh->m_fields[i] + ",";
1102  }
1103  fstr = fstr.substr(0, fstr.length() - 1);
1104  exp->SetAttribute("FIELDS", fstr);
1105  }
1106 
1107  expansions->LinkEndChild(exp);
1108  }
1109  }
1110  pRoot->LinkEndChild(expansions);
1111 }
1112 
1113 void OutputNekpp::WriteXmlConditions(TiXmlElement *pRoot)
1114 {
1115  TiXmlElement *conditions = new TiXmlElement("CONDITIONS");
1116  TiXmlElement *boundaryregions = new TiXmlElement("BOUNDARYREGIONS");
1117  TiXmlElement *boundaryconditions = new TiXmlElement("BOUNDARYCONDITIONS");
1118  TiXmlElement *variables = new TiXmlElement("VARIABLES");
1120 
1121  for (it = m_mesh->m_condition.begin(); it != m_mesh->m_condition.end();
1122  ++it)
1123  {
1124  ConditionSharedPtr c = it->second;
1125  string tmp;
1126 
1127  // First set up boundary regions.
1128  TiXmlElement *b = new TiXmlElement("B");
1129  b->SetAttribute("ID", boost::lexical_cast<string>(it->first));
1130 
1131  for (int i = 0; i < c->m_composite.size(); ++i)
1132  {
1133  tmp += boost::lexical_cast<string>(c->m_composite[i]) + ",";
1134  }
1135 
1136  tmp = tmp.substr(0, tmp.length() - 1);
1137 
1138  TiXmlText *t0 = new TiXmlText("C[" + tmp + "]");
1139  b->LinkEndChild(t0);
1140  boundaryregions->LinkEndChild(b);
1141 
1142  TiXmlElement *region = new TiXmlElement("REGION");
1143  region->SetAttribute("REF", boost::lexical_cast<string>(it->first));
1144 
1145  for (int i = 0; i < c->type.size(); ++i)
1146  {
1147  string tagId;
1148 
1149  switch (c->type[i])
1150  {
1151  case eDirichlet:
1152  tagId = "D";
1153  break;
1154  case eNeumann:
1155  tagId = "N";
1156  break;
1157  case ePeriodic:
1158  tagId = "P";
1159  break;
1160  case eHOPCondition:
1161  tagId = "N";
1162  break;
1163  default:
1164  break;
1165  }
1166 
1167  TiXmlElement *tag = new TiXmlElement(tagId);
1168  tag->SetAttribute("VAR", c->field[i]);
1169  tag->SetAttribute("VALUE", c->value[i]);
1170 
1171  if (c->type[i] == eHOPCondition)
1172  {
1173  tag->SetAttribute("USERDEFINEDTYPE", "H");
1174  }
1175 
1176  region->LinkEndChild(tag);
1177  }
1178 
1179  boundaryconditions->LinkEndChild(region);
1180  }
1181 
1182  for (int i = 0; i < m_mesh->m_fields.size(); ++i)
1183  {
1184  TiXmlElement *v = new TiXmlElement("V");
1185  v->SetAttribute("ID", boost::lexical_cast<std::string>(i));
1186  TiXmlText *t0 = new TiXmlText(m_mesh->m_fields[i]);
1187  v->LinkEndChild(t0);
1188  variables->LinkEndChild(v);
1189  }
1190 
1191  if (m_mesh->m_fields.size() > 0)
1192  {
1193  conditions->LinkEndChild(variables);
1194  }
1195 
1196  if (m_mesh->m_condition.size() > 0)
1197  {
1198  conditions->LinkEndChild(boundaryregions);
1199  conditions->LinkEndChild(boundaryconditions);
1200  }
1201 
1202  pRoot->LinkEndChild(conditions);
1203 }
1204 }
1205 }
void WriteXmlCurves(TiXmlElement *pRoot)
Writes the section of the XML file if needed.
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
virtual void Process()
Write mesh to output file.
Definition: OutputNekpp.cpp:96
static boost::shared_ptr< MeshGraph > Read(const LibUtilities::SessionReaderSharedPtr &pSession, DomainRangeShPtr &rng=NullDomainRangeShPtr)
Definition: MeshGraph.cpp:124
NekInt64 ptoffset
the id of point data map (currently always 0 since we are using just one set).
void WriteXmlFaces(TiXmlElement *pRoot)
Writes the section of the XML file if needed.
const std::string kPointsTypeStr[]
Definition: Foundations.hpp:69
void WriteXmlNodes(TiXmlElement *pRoot)
Writes the section of the XML file.
std::vector< NekInt64 > index
id of this Point set
Abstract base class for output modules.
STL namespace.
pair< ModuleType, string > ModuleKey
void TestElmts(SpatialDomains::MeshGraphSharedPtr &graph)
Definition: OutputNekpp.cpp:79
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:51
NekInt64 entityid
Id of this curved information.
boost::unordered_set< NodeSharedPtr, NodeHash > NodeSet
Definition: Node.h:441
1D Evenly-spaced points using Lagrange polynomial
Definition: PointsType.h:65
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
string GetXmlString(char tag, vector< unsigned int > &ids)
NekInt64 npoints
The entity id corresponding to the global edge/curve.
Represents a command-line configuration option.
boost::shared_ptr< Node > NodeSharedPtr
Definition: Node.h:50
std::map< std::string, ConfigOption > m_config
List of configuration values.
boost::shared_ptr< Condition > ConditionSharedPtr
Definition: Mesh.h:82
int ZlibEncodeToBase64Str(std::vector< T > &in, std::string &out64)
Definition: CompressData.h:151
NekInt64 ptype
point offset of data entry for this curve
void WriteXmlExpansions(TiXmlElement *pRoot)
Writes the section of the XML file.
boost::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
Definition: Edge.h:136
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
boost::shared_ptr< Mesh > MeshSharedPtr
Shared pointer to a mesh.
Definition: Mesh.h:147
void WriteXmlDomain(TiXmlElement *pRoot)
Writes the section of the XML file.
void WriteXmlComposites(TiXmlElement *pRoot)
Writes the section of the XML file.
void WriteXmlElements(TiXmlElement *pRoot)
Writes the section of the XML file.
NekInt64 ptid
The number of points in this curved entity.
std::vector< MeshVertex > pts
mapping to access pts value.
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
Definition: StdRegions.hpp:316
void WriteXmlConditions(TiXmlElement *pRoot)
Writes the section of the XML file.
boost::unordered_map< int, CurveSharedPtr > CurveMap
Definition: Curve.hpp:63
boost::shared_ptr< Face > FaceSharedPtr
Definition: Face.h:153
void WriteXmlEdges(TiXmlElement *pRoot)
Writes the section of the XML file.
std::pair< ModuleType, std::string > ModuleKey
boost::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:442
boost::shared_ptr< Geometry > GeometrySharedPtr
Definition: Geometry.h:53
ModuleFactory & GetModuleFactory()
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:215