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

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

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

References ASSERTL0, ErrorUtil::efatal, GetXmlString(), Nektar::iterator, and NEKERROR.

Referenced by main().

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

References ASSERTL0, ErrorUtil::efatal, and NEKERROR.

Referenced by main().

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

References ASSERTL0, ErrorUtil::efatal, and NEKERROR.

Referenced by main().

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

Error value returned by TinyXML.

Definition at line 115 of file ExpandMeshByRotation.cpp.

References ASSERTL0, npts, and Vmath::Vmax().

Referenced by main().

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

Definition at line 430 of file ExpandMeshByRotation.cpp.

References Nektar::iterator.

Referenced by ExpandComposites(), and Nektar::Utilities::OutputNekpp::WriteXmlElements().

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

Definition at line 60 of file ExpandMeshByRotation.cpp.

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

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