Nektar++
Functions
ExpandMeshByRotation.cpp File Reference
#include <LibUtilities/BasicConst/NektarUnivTypeDefs.hpp>
#include <LibUtilities/BasicUtils/ParseUtils.h>
#include <LibUtilities/BasicUtils/SessionReader.h>
#include <SpatialDomains/MeshGraph.h>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <map>
#include <iomanip>
#include <tinyxml.h>

Go to the source code of this file.

Functions

void ExpandVertices (TiXmlElement *mesh, map< int, int > jointVerts, map< int, int > &fullVerts)
 
void ExpandEdges (TiXmlElement *mesh, map< int, int > &newVerts, map< int, int > jointEdges, map< int, int > &newEdges)
 
void ExpandElmts (TiXmlElement *mesh, map< int, int > &newEdges, int &nOrigElmts)
 
void ExpandComposites (TiXmlElement *mesh, map< int, int > fullEdges, int nOrigElmts)
 
int main (int argc, char *argv[])
 
string GetXmlString (char tag, vector< unsigned int > &ids)
 

Function Documentation

◆ ExpandComposites()

void ExpandComposites ( TiXmlElement *  mesh,
map< int, int >  fullEdges,
int  nOrigElmts 
)

All elements are of the form: "<C ID = "N"> ... </C>". Read the ID field first.

Parse out the element components corresponding to type of element.

Keep looking

Definition at line 471 of file ExpandMeshByRotation.cpp.

References ASSERTL0, GetXmlString(), and NEKERROR.

Referenced by main().

472 {
473  TiXmlElement* field = mesh->FirstChildElement("COMPOSITE");
474  ASSERTL0(field, "Unable to find COMPOSITE tag in file.");
475 
476  int nextCompositeNumber = -1;
477 
478  /// All elements are of the form: "<C ID = "N"> ... </C>".
479  /// Read the ID field first.
480  TiXmlElement *composite = field->FirstChildElement("C");
481 
482  while (composite)
483  {
484  nextCompositeNumber++;
485 
486  int indx;
487  int err = composite->QueryIntAttribute("ID", &indx);
488  ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
489 
490  TiXmlNode* compositeChild = composite->FirstChild();
491  // This is primarily to skip comments that may be present.
492  // Comments appear as nodes just like elements.
493  // We are specifically looking for text in the body
494  // of the definition.
495  while(compositeChild && compositeChild->Type() != TiXmlNode::TINYXML_TEXT)
496  {
497  compositeChild = compositeChild->NextSibling();
498  }
499 
500  ASSERTL0(compositeChild, "Unable to read composite definition body.");
501  std::string compositeStr = compositeChild->ToText()->ValueStr();
502 
503  /// Parse out the element components corresponding to type of element.
504  std::istringstream compositeDataStrm(compositeStr.c_str());
505 
506 
507  try
508  {
509 
510  std::string compositeElementStr;
511  compositeDataStrm >> compositeElementStr;
512 
513  std::istringstream tokenStream(compositeElementStr);
514  char type;
515 
516  tokenStream >> type;
517 
518  // in what follows we are assuming there is only one block of data
519  std::string::size_type indxBeg = compositeElementStr.find_first_of('[') + 1;
520  std::string::size_type indxEnd = compositeElementStr.find_last_of(']') - 1;
521 
522  ASSERTL0(indxBeg <= indxEnd, (std::string("Error reading index definition:") + compositeElementStr).c_str());
523 
524  std::string indxStr = compositeElementStr.substr(indxBeg, indxEnd - indxBeg + 1);
525  std::vector<unsigned int> seqVector;
526 
527  bool err = ParseUtils::GenerateSeqVector(indxStr, seqVector);
528 
529  ASSERTL0(err, (std::string("Error reading composite elements: ") + indxStr).c_str());
530 
531  switch(type)
532  {
533  case 'E': // Expand edges using newEdges map and known values
534  {
535  int seqlen = seqVector.size();
536  int nedges = newEdges.size();
537 
538  map<unsigned int, unsigned int> seqMap;
539 
540  for(int i =0; i < seqlen; ++i) // set up a map of defined edges
541  {
542  seqMap[seqVector[i]] = 1;
543  }
544 
545  // if edge does not exist in composite add it to the list
546  for(int i =0; i < seqlen; ++i)
547  {
548  if(seqMap.count(newEdges[seqVector[i]+nedges]) == 0)
549  {
550  seqVector.push_back(newEdges[seqVector[i]+nedges]);
551  }
552  }
553  }
554  break;
555 
556  case 'T': case 'Q': // Expand Triangles & Quads with new elements
557  {
558  int seqlen = seqVector.size();
559 
560  for(int i = 0; i < seqlen; ++i)
561  {
562  seqVector.push_back(seqVector[i]+nOrigElmts);
563  }
564 
565  break;
566  }
567  default:
568  NEKERROR(ErrorUtil::efatal, (std::string("Unrecognized composite token: ") + compositeElementStr).c_str());
569  }
570 
571  // now redefine string in composite
572 
573 
574  composite->ReplaceChild(compositeChild, TiXmlText(GetXmlString(type,seqVector)));
575 
576 
577  }
578  catch(...)
579  {
580  NEKERROR(ErrorUtil::efatal,
581  (std::string("Unable to read COMPOSITE data for composite: ") + compositeStr).c_str());
582  }
583 
584  /// Keep looking
585  composite = composite->NextSiblingElement("C");
586  }
587 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:209
string GetXmlString(char tag, vector< unsigned int > &ids)

◆ ExpandEdges()

void ExpandEdges ( TiXmlElement *  mesh,
map< int, int > &  newVerts,
map< int, int >  jointEdges,
map< int, int > &  newEdges 
)

Look for elements in ELEMENT block.

All elements are of the form: "<E ID="#"> ... </E>", with ? being the element type. Read the ID field first.

Since all edge data is one big text block, we need to accumulate all TINYXML_TEXT data and then parse it. This approach effectively skips all comments or other node types since we only care about the edge list. We cannot handle missing edge numbers as we could with missing element numbers due to the text block format.

Now parse out the edges, three fields at a time.

Definition at line 209 of file ExpandMeshByRotation.cpp.

References ASSERTL0, and NEKERROR.

Referenced by main().

210 {
211  /// Look for elements in ELEMENT block.
212  TiXmlElement* field = mesh->FirstChildElement("EDGE");
213 
214  ASSERTL0(field, "Unable to find EDGE tag in file.");
215 
216  /// All elements are of the form: "<E ID="#"> ... </E>", with
217  /// ? being the element type.
218  /// Read the ID field first.
219  TiXmlElement *edge = field->FirstChildElement("E");
220 
221  /// Since all edge data is one big text block, we need to
222  /// accumulate all TINYXML_TEXT data and then parse it. This
223  /// approach effectively skips all comments or other node
224  /// types since we only care about the edge list. We
225  /// cannot handle missing edge numbers as we could with
226  /// missing element numbers due to the text block format.
227  std::string edgeStr;
228  int indx;
229  int nextEdgeNumber = -1;
230 
231  map<int,int> edgeVert0,edgeVert1;
232  while(edge)
233  {
234  nextEdgeNumber++;
235 
236  int err = edge->QueryIntAttribute("ID",&indx);
237  ASSERTL0(err == TIXML_SUCCESS, "Unable to read edge attribute ID.");
238 
239  TiXmlNode *child = edge->FirstChild();
240  edgeStr.clear();
241  if (child->Type() == TiXmlNode::TINYXML_TEXT)
242  {
243  edgeStr += child->ToText()->ValueStr();
244  }
245 
246  /// Now parse out the edges, three fields at a time.
247  int vertex1, vertex2;
248  std::istringstream edgeDataStrm(edgeStr.c_str());
249 
250  try
251  {
252  while (!edgeDataStrm.fail())
253  {
254  edgeDataStrm >> vertex1 >> vertex2;
255  }
256  edgeVert0[indx] = vertex1;
257  edgeVert1[indx] = vertex2;
258  }
259  catch(...)
260  {
261  NEKERROR(ErrorUtil::efatal, (std::string("Unable to read edge data: ") + edgeStr).c_str());
262  }
263  edge = edge->NextSiblingElement("E");
264  }
265 
266  int nedges = edgeVert0.size();
267  int cnt = nedges;
268  int cnt1 = nedges;
269  int norigverts = newVerts.size();
270 
271  for(int i = 0; i < nedges; ++i)
272  {
273  if(jointEdges.count(i) == 0)
274  {
275  stringstream s;
276 
277  s << setw(5) << newVerts[edgeVert0[i]+norigverts] << " "
278  << newVerts[edgeVert1[i]+norigverts] << " ";
279  TiXmlElement * e = new TiXmlElement( "E" );
280  e->SetAttribute("ID",cnt1);
281  e->LinkEndChild( new TiXmlText(s.str()) );
282  field->LinkEndChild(e);
283  newEdges[cnt++] = cnt1++;
284  }
285  else
286  {
287  newEdges[cnt++] = jointEdges[i];
288  }
289  }
290 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:209

◆ ExpandElmts()

void ExpandElmts ( TiXmlElement *  mesh,
map< int, int > &  newEdges,
int &  nOrigElmts 
)

All elements are of the form: "<? ID="#"> ... </?>", with ? being the element type.

These should be ordered.

Read id attribute.

Read text element description.

Parse out the element components corresponding to type of element.

Keep looking

Definition at line 292 of file ExpandMeshByRotation.cpp.

References ASSERTL0, and NEKERROR.

Referenced by main().

293 {
294 
295  TiXmlElement* field = mesh->FirstChildElement("ELEMENT");
296 
297  ASSERTL0(field, "Unable to find ELEMENT tag in file.");
298 
299  int nextElementNumber = -1;
300 
301  /// All elements are of the form: "<? ID="#"> ... </?>", with
302  /// ? being the element type.
303 
304  TiXmlElement *element = field->FirstChildElement();
305 
306  map<int,vector<int> > ElmtEdges;
307 
308  while (element)
309  {
310  std::string elementType(element->ValueStr());
311 
312  ASSERTL0(elementType == "Q" || elementType == "T",
313  (std::string("Unknown 2D element type: ") + elementType).c_str());
314 
315  /// These should be ordered.
316  nextElementNumber++;
317 
318  /// Read id attribute.
319  int indx;
320  int err = element->QueryIntAttribute("ID", &indx);
321  ASSERTL0(err == TIXML_SUCCESS, "Unable to read element attribute ID.");
322 
323  /// Read text element description.
324  TiXmlNode* elementChild = element->FirstChild();
325  std::string elementStr;
326  while(elementChild)
327  {
328  if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
329  {
330  elementStr += elementChild->ToText()->ValueStr();
331  }
332  elementChild = elementChild->NextSibling();
333  }
334 
335  ASSERTL0(!elementStr.empty(), "Unable to read element description body.");
336 
337  /// Parse out the element components corresponding to type of element.
338  if (elementType == "T")
339  {
340  // Read three edge numbers
341  int edge1, edge2, edge3;
342  std::istringstream elementDataStrm(elementStr.c_str());
343 
344  try
345  {
346  elementDataStrm >> edge1;
347  elementDataStrm >> edge2;
348  elementDataStrm >> edge3;
349 
350  ASSERTL0(!elementDataStrm.fail(), (std::string("Unable to read element data for TRIANGLE: ") + elementStr).c_str());
351 
352  vector<int> edges;
353  edges.push_back(edge1);
354  edges.push_back(edge2);
355  edges.push_back(edge3);
356 
357  ElmtEdges[indx] = edges;
358  }
359  catch(...)
360  {
361  NEKERROR(ErrorUtil::efatal, (std::string("Unable to read element data for TRIANGLE: ") + elementStr).c_str());
362  }
363  }
364  else if (elementType == "Q")
365  {
366  // Read four edge numbers
367  int edge1, edge2, edge3, edge4;
368  std::istringstream elementDataStrm(elementStr.c_str());
369 
370  try
371  {
372  elementDataStrm >> edge1;
373  elementDataStrm >> edge2;
374  elementDataStrm >> edge3;
375  elementDataStrm >> edge4;
376 
377  ASSERTL0(!elementDataStrm.fail(), (std::string("Unable to read element data for QUAD: ") + elementStr).c_str());
378 
379  vector<int> edges;
380  edges.push_back(edge1);
381  edges.push_back(edge2);
382  edges.push_back(edge3);
383  edges.push_back(edge4);
384 
385  ElmtEdges[indx] = edges;
386 
387  }
388  catch(...)
389  {
390  NEKERROR(ErrorUtil::efatal,(std::string("Unable to read element data for QUAD: ") + elementStr).c_str());
391  }
392  }
393 
394  /// Keep looking
395  element = element->NextSiblingElement();
396  }
397 
398  nelmts = ElmtEdges.size();
399  int nedges = newEdges.size();
400 
401  for(int i = 0; i < ElmtEdges.size(); ++i)
402  {
403  stringstream s;
404 
405  for(int j = 0; j < ElmtEdges[i].size() ; ++j)
406  {
407  s << setw(10) << newEdges[ElmtEdges[i][j]+nedges];
408  }
409 
410  TiXmlElement * f;
411  switch(ElmtEdges[i].size())
412  {
413  case 3:
414  f = new TiXmlElement("T");
415  break;
416  case 4:
417  f = new TiXmlElement("Q");
418  break;
419  default:
420  abort();
421  }
422  f->SetAttribute("ID", i+nelmts);
423  f->LinkEndChild( new TiXmlText(s.str()));
424  field->LinkEndChild(f);
425  }
426 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:209

◆ ExpandVertices()

void ExpandVertices ( TiXmlElement *  mesh,
map< int, int >  jointVerts,
map< int, int > &  fullVerts 
)

Error value returned by TinyXML.

Definition at line 114 of file ExpandMeshByRotation.cpp.

References ASSERTL0, and Vmath::Vmax().

Referenced by main().

115 {
116 
117  TiXmlElement* element = mesh->FirstChildElement("VERTEX");
118  ASSERTL0(element, "Unable to find mesh VERTEX tag in file.");
119 
120  TiXmlElement *vertex = element->FirstChildElement("V");
121 
122  int indx;
123  int nextVertexNumber = -1;
124  int err; /// Error value returned by TinyXML.
125 
126  vector<NekDouble> xpts,ypts,zpts;
127  NekDouble xval, yval, zval;
128 
129  NekDouble yoffset = 0.0;
130  while (vertex)
131  {
132  nextVertexNumber++;
133 
134  TiXmlAttribute *vertexAttr = vertex->FirstAttribute();
135  std::string attrName(vertexAttr->Name());
136 
137  ASSERTL0(attrName == "ID", (std::string("Unknown attribute name: ") + attrName).c_str());
138 
139  err = vertexAttr->QueryIntValue(&indx);
140  ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
141 
142  // Now read body of vertex
143  std::string vertexBodyStr;
144 
145  TiXmlNode *vertexBody = vertex->FirstChild();
146 
147  while (vertexBody)
148  {
149  // Accumulate all non-comment body data.
150  if (vertexBody->Type() == TiXmlNode::TINYXML_TEXT)
151  {
152  vertexBodyStr += vertexBody->ToText()->Value();
153  vertexBodyStr += " ";
154  }
155 
156  vertexBody = vertexBody->NextSibling();
157  }
158 
159  ASSERTL0(!vertexBodyStr.empty(), "Vertex definitions must contain vertex data.");
160 
161  // Get vertex data from the data string.
162  std::istringstream vertexDataStrm(vertexBodyStr.c_str());
163 
164  try
165  {
166  while(!vertexDataStrm.fail())
167  {
168  vertexDataStrm >> xval >> yval >> zval;
169  }
170  xpts.push_back(xval);
171  ypts.push_back(yval +yoffset);
172  zpts.push_back(zval);
173  }
174  catch(...)
175  {
176  ASSERTL0(false, "Unable to read VERTEX data.");
177  }
178  vertex = vertex->NextSiblingElement("V");
179  }
180 
181  // Add in newvertices
182  int npts = xpts.size();
183  NekDouble xmax = Vmath::Vmax(npts,&xpts[0],1);
184  int cnt = npts;
185  int cnt1 = npts;
186 
187  for(int i = 0; i < npts; ++i)
188  {
189  if(jointVerts.count(i) == 0)
190  {
191  stringstream s;
192  xval = xmax - xpts[i];
193  yval = -ypts[i];
194  s << scientific << setprecision(8)
195  << xval << " " << yval << " " << zpts[i];
196  TiXmlElement * v = new TiXmlElement( "V" );
197  v->SetAttribute("ID",cnt1);
198  v->LinkEndChild(new TiXmlText(s.str()));
199  element->LinkEndChild(v);
200  newVerts[cnt++] = cnt1++;
201  }
202  else
203  {
204  newVerts[cnt++] = jointVerts[i];
205  }
206  }
207 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
Definition: Vmath.cpp:782
double NekDouble

◆ GetXmlString()

string GetXmlString ( char  tag,
vector< unsigned int > &  ids 
)

Definition at line 429 of file ExpandMeshByRotation.cpp.

Referenced by ExpandComposites().

430 {
431  stringstream st;
432  bool range = false;
433  int vId = ids[0];
434  int prevId = vId;
435 
436  st << " " << tag << "[" << vId;
437 
438  for (auto it = ids.begin()+1; it != ids.end(); ++it){
439  // store previous element ID and get current one
440  prevId = vId;
441  vId = (*it);
442 
443  // continue an already started range
444  if (prevId > -1 && vId == prevId + 1)
445  {
446  range = true;
447  // if this is the last element, it's the end of a range, so write
448  if (*it == ids.back())
449  {
450  st << "-" << vId;
451  }
452  continue;
453  }
454 
455  // terminate a range, if present
456  if (range)
457  {
458  st << "-" << prevId;
459  range = false;
460  }
461 
462  // write what will be either a single entry or start of new range
463  st << "," << vId;
464  }
465  // terminate
466  st << "] ";
467  return st.str();
468 }

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 59 of file ExpandMeshByRotation.cpp.

References ExpandComposites(), ExpandEdges(), ExpandElmts(), and ExpandVertices().

60 {
61  int i;
62 
63  if(argc !=3)
64  {
65  fprintf(stderr,"Usage: ./ExpandMeshByRotation meshfile outfile\n");
66  exit(1);
67  }
68 
69  //------------------------------------------------------------
70  // Create Session file which also reads meshfile.
72  = LibUtilities::SessionReader::CreateInstance(argc-1, argv);
73  //-----------------------------------------------------------
74 
75  //-------------------------------------------------------------
76  // Read in mesh from input file
77  string meshfile(argv[argc-2]);
78  SpatialDomains::MeshGraphSharedPtr graphShPt=SpatialDomains::MeshGraph::Read(vSession);
80  composite = graphShPt->GetComposite(300);
81  std::map<int,int> jointEdges, jointVerts, newVerts, newEdges;
82  int compsize = composite->m_geomVec.size();
83  for(i = 0; i < compsize; ++i)
84  {
85  SpatialDomains::Geometry1DSharedPtr tmp1 = std::dynamic_pointer_cast<SpatialDomains::Geometry1D>(composite->m_geomVec[i]);
86  SpatialDomains::Geometry1DSharedPtr tmp2 = std::dynamic_pointer_cast<SpatialDomains::Geometry1D>(composite->m_geomVec[compsize-1-i]);
87  jointEdges[tmp1->GetGlobalID()] = tmp2->GetGlobalID();
88  jointVerts[tmp1->GetVid(0)] = tmp2->GetVid(1);
89  jointVerts[tmp1->GetVid(1)] = tmp2->GetVid(0);
90  }
91 
92 
93  //------------------------------------------------------------
94  TiXmlDocument& meshdoc = vSession->GetDocument();
95 
96  TiXmlHandle docHandle(&meshdoc);
97  TiXmlElement* mesh = docHandle.FirstChildElement("NEKTAR").FirstChildElement("GEOMETRY").Element();
98 
99  int nOrigElmts;
100  //------------------------------------------------------------
101  // Expand Mesh
102  ExpandVertices(mesh,jointVerts,newVerts);
103 
104  ExpandEdges(mesh,newVerts,jointEdges,newEdges);
105 
106  ExpandElmts(mesh, newEdges,nOrigElmts);
107 
108  ExpandComposites( mesh, newEdges, nOrigElmts);
109 
110  meshdoc.SaveFile(argv[argc-1]);
111 
112 }
void ExpandElmts(TiXmlElement *mesh, map< int, int > &newEdges, int &nOrigElmts)
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:163
std::shared_ptr< Composite > CompositeSharedPtr
Definition: MeshGraph.h:136
void ExpandComposites(TiXmlElement *mesh, map< int, int > fullEdges, int nOrigElmts)
1D geometry information
Definition: Geometry1D.h:54
void ExpandVertices(TiXmlElement *mesh, map< int, int > jointVerts, map< int, int > &fullVerts)
void ExpandEdges(TiXmlElement *mesh, map< int, int > &newVerts, map< int, int > jointEdges, map< int, int > &newEdges)
std::shared_ptr< Geometry1D > Geometry1DSharedPtr
Definition: Geometry.h:63
std::shared_ptr< SessionReader > SessionReaderSharedPtr