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:940

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:176
std::shared_ptr< Geometry1D > Geometry1DSharedPtr
Definition: Geometry.h:64

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