Nektar++
Loading...
Searching...
No Matches
Functions
ExpandMeshByRotation.cpp File Reference
#include <LibUtilities/BasicConst/NektarUnivTypeDefs.hpp>
#include <LibUtilities/BasicUtils/ParseUtils.h>
#include <LibUtilities/BasicUtils/SessionReader.h>
#include <SpatialDomains/MeshGraphIO.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 489 of file ExpandMeshByRotation.cpp.

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

References ASSERTL0, Nektar::ErrorUtil::efatal, Nektar::ParseUtils::GenerateSeqVector(), 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 215 of file ExpandMeshByRotation.cpp.

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

References ASSERTL0, Nektar::ErrorUtil::efatal, 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 298 of file ExpandMeshByRotation.cpp.

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

References ASSERTL0, Nektar::ErrorUtil::efatal, 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 120 of file ExpandMeshByRotation.cpp.

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

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

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.
75 //-----------------------------------------------------------
76
77 //-------------------------------------------------------------
78 // Read in mesh from input file
79 string meshfile(argv[argc - 2]);
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 dynamic_cast<SpatialDomains::Geometry1D *>(composite->m_geomVec[i]);
91 dynamic_cast<SpatialDomains::Geometry1D *>(
92 composite->m_geomVec[compsize - 1 - i]);
93 jointEdges[tmp1->GetGlobalID()] = tmp2->GetGlobalID();
94 jointVerts[tmp1->GetVid(0)] = tmp2->GetVid(1);
95 jointVerts[tmp1->GetVid(1)] = tmp2->GetVid(0);
96 }
97
98 //------------------------------------------------------------
99 TiXmlDocument &meshdoc = vSession->GetDocument();
100
101 TiXmlHandle docHandle(&meshdoc);
102 TiXmlElement *mesh = docHandle.FirstChildElement("NEKTAR")
103 .FirstChildElement("GEOMETRY")
104 .Element();
105
106 int nOrigElmts;
107 //------------------------------------------------------------
108 // Expand Mesh
109 ExpandVertices(mesh, jointVerts, newVerts);
110
111 ExpandEdges(mesh, newVerts, jointEdges, newEdges);
112
113 ExpandElmts(mesh, newEdges, nOrigElmts);
114
115 ExpandComposites(mesh, newEdges, nOrigElmts);
116
117 meshdoc.SaveFile(argv[argc - 1]);
118}
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)
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
1D geometry information
Definition Geometry1D.h:49
int GetVid(int i) const
Returns global id of vertex i of this object.
Definition Geometry.h:353
int GetGlobalID(void) const
Get the ID of this object.
Definition Geometry.h:322
static MeshGraphSharedPtr Read(const LibUtilities::SessionReaderSharedPtr pSession, LibUtilities::DomainRangeShPtr rng=LibUtilities::NullDomainRangeShPtr, bool fillGraph=true, SpatialDomains::MeshGraphSharedPtr partitionedGraph=nullptr)
std::shared_ptr< SessionReader > SessionReaderSharedPtr
std::shared_ptr< Composite > CompositeSharedPtr
Definition MeshGraph.h:178
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition MeshGraph.h:217

References Nektar::LibUtilities::SessionReader::CreateInstance(), ExpandComposites(), ExpandEdges(), ExpandElmts(), ExpandVertices(), Nektar::SpatialDomains::Geometry::GetGlobalID(), Nektar::SpatialDomains::Geometry::GetVid(), and Nektar::SpatialDomains::MeshGraphIO::Read().