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

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

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

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.

Read id attribute.

Read text element description.

Parse out the element components corresponding to type of element.

Keep looking

Definition at line 299 of file ExpandMeshByRotation.cpp.

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

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

References ASSERTL0, and Vmath::Vmax().

Referenced by main().

◆ GetXmlString()

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

Definition at line 448 of file ExpandMeshByRotation.cpp.

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

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:135
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:174
std::shared_ptr< Geometry1D > Geometry1DSharedPtr
Definition: Geometry.h:61

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