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 <iomanip>
#include <map>
#include <sstream>
#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 501 of file ExpandMeshByRotation.cpp.

503 {
504  TiXmlElement *field = mesh->FirstChildElement("COMPOSITE");
505  ASSERTL0(field, "Unable to find COMPOSITE tag in file.");
506 
507  int nextCompositeNumber = -1;
508 
509  /// All elements are of the form: "<C ID = "N"> ... </C>".
510  /// Read the ID field first.
511  TiXmlElement *composite = field->FirstChildElement("C");
512 
513  while (composite)
514  {
515  nextCompositeNumber++;
516 
517  int indx;
518  int err = composite->QueryIntAttribute("ID", &indx);
519  ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
520 
521  TiXmlNode *compositeChild = composite->FirstChild();
522  // This is primarily to skip comments that may be present.
523  // Comments appear as nodes just like elements.
524  // We are specifically looking for text in the body
525  // of the definition.
526  while (compositeChild &&
527  compositeChild->Type() != TiXmlNode::TINYXML_TEXT)
528  {
529  compositeChild = compositeChild->NextSibling();
530  }
531 
532  ASSERTL0(compositeChild, "Unable to read composite definition body.");
533  std::string compositeStr = compositeChild->ToText()->ValueStr();
534 
535  /// Parse out the element components corresponding to type of element.
536  std::istringstream compositeDataStrm(compositeStr.c_str());
537 
538  try
539  {
540 
541  std::string compositeElementStr;
542  compositeDataStrm >> compositeElementStr;
543 
544  std::istringstream tokenStream(compositeElementStr);
545  char type;
546 
547  tokenStream >> type;
548 
549  // in what follows we are assuming there is only one block of data
550  std::string::size_type indxBeg =
551  compositeElementStr.find_first_of('[') + 1;
552  std::string::size_type indxEnd =
553  compositeElementStr.find_last_of(']') - 1;
554 
555  ASSERTL0(indxBeg <= indxEnd,
556  (std::string("Error reading index definition:") +
557  compositeElementStr)
558  .c_str());
559 
560  std::string indxStr =
561  compositeElementStr.substr(indxBeg, indxEnd - indxBeg + 1);
562  std::vector<unsigned int> seqVector;
563 
564  bool err = ParseUtils::GenerateSeqVector(indxStr, seqVector);
565 
566  ASSERTL0(err, (std::string("Error reading composite elements: ") +
567  indxStr)
568  .c_str());
569 
570  switch (type)
571  {
572  case 'E': // Expand edges using newEdges map and known values
573  {
574  int seqlen = seqVector.size();
575  int nedges = newEdges.size();
576 
577  map<unsigned int, unsigned int> seqMap;
578 
579  for (int i = 0; i < seqlen;
580  ++i) // set up a map of defined edges
581  {
582  seqMap[seqVector[i]] = 1;
583  }
584 
585  // if edge does not exist in composite add it to the list
586  for (int i = 0; i < seqlen; ++i)
587  {
588  if (seqMap.count(newEdges[seqVector[i] + nedges]) == 0)
589  {
590  seqVector.push_back(
591  newEdges[seqVector[i] + nedges]);
592  }
593  }
594  }
595  break;
596 
597  case 'T':
598  case 'Q': // Expand Triangles & Quads with new elements
599  {
600  int seqlen = seqVector.size();
601 
602  for (int i = 0; i < seqlen; ++i)
603  {
604  seqVector.push_back(seqVector[i] + nOrigElmts);
605  }
606 
607  break;
608  }
609  default:
610  NEKERROR(ErrorUtil::efatal,
611  (std::string("Unrecognized composite token: ") +
612  compositeElementStr)
613  .c_str());
614  }
615 
616  // now redefine string in composite
617 
618  composite->ReplaceChild(compositeChild,
619  TiXmlText(GetXmlString(type, seqVector)));
620  }
621  catch (...)
622  {
623  NEKERROR(
624  ErrorUtil::efatal,
625  (std::string("Unable to read COMPOSITE data for composite: ") +
626  compositeStr)
627  .c_str());
628  }
629 
630  /// Keep looking
631  composite = composite->NextSiblingElement("C");
632  }
633 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:215
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
Definition: ErrorUtil.hpp:209
string GetXmlString(char tag, vector< unsigned int > &ids)

References ASSERTL0, GetXmlString(), and NEKERROR.

Referenced by main().

◆ 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 219 of file ExpandMeshByRotation.cpp.

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

References ASSERTL0, and NEKERROR.

Referenced by main().

◆ 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 305 of file ExpandMeshByRotation.cpp.

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

References ASSERTL0, and NEKERROR.

Referenced by main().

◆ ExpandVertices()

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

Error value returned by TinyXML.

Definition at line 121 of file ExpandMeshByRotation.cpp.

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

References ASSERTL0, and Vmath::Vmax().

Referenced by main().

◆ GetXmlString()

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

Definition at line 459 of file ExpandMeshByRotation.cpp.

460 {
461  stringstream st;
462  bool range = false;
463  int vId = ids[0];
464  int prevId = vId;
465 
466  st << " " << tag << "[" << vId;
467 
468  for (auto it = ids.begin() + 1; it != ids.end(); ++it)
469  {
470  // store previous element ID and get current one
471  prevId = vId;
472  vId = (*it);
473 
474  // continue an already started range
475  if (prevId > -1 && vId == prevId + 1)
476  {
477  range = true;
478  // if this is the last element, it's the end of a range, so write
479  if (*it == ids.back())
480  {
481  st << "-" << vId;
482  }
483  continue;
484  }
485 
486  // terminate a range, if present
487  if (range)
488  {
489  st << "-" << prevId;
490  range = false;
491  }
492 
493  // write what will be either a single entry or start of new range
494  st << "," << vId;
495  }
496  // terminate
497  st << "] ";
498  return st.str();
499 }

Referenced by ExpandComposites().

◆ main()

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

Definition at line 61 of file ExpandMeshByRotation.cpp.

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

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