Nektar++
Loading...
Searching...
No Matches
Classes | Enumerations | Functions
MoveMeshToCriticalLayer.cpp File Reference
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <LibUtilities/BasicUtils/ParseUtils.h>
#include <MultiRegions/ExpList.h>
#include <SpatialDomains/MeshGraphIO.h>
#include <tinyxml.h>
#include "ExtractCriticalLayerFunctions.h"

Go to the source code of this file.

Classes

struct  MoveVerts
 

Enumerations

enum  SolveType { eSolveX , eSolveY , eSolveXY , eNoSolve }
 

Functions

void GetInterfaceVerts (const int compositeID, SpatialDomains::MeshGraphSharedPtr &mesh, vector< int > &InterfaceVerts)
 
void GetStreakLocation (LibUtilities::SessionReaderSharedPtr &vSession, SpatialDomains::MeshGraphSharedPtr &mesh, string &fieldfile, Array< OneD, NekDouble > &xc, Array< OneD, NekDouble > &yc)
 
void GetNewVertexLocation (TiXmlElement *doc, SpatialDomains::MeshGraphSharedPtr &mesh, vector< int > &InterfaceVerts, Array< OneD, NekDouble > &xstreak, Array< OneD, NekDouble > &ystreak, Array< OneD, NekDouble > &vertx, Array< OneD, NekDouble > &verty, int maxiter)
 
void TurnOffEdges (TiXmlElement *doc, SpatialDomains::MeshGraphSharedPtr &mesh, Array< OneD, MoveVerts > &verts)
 
void RedefineVertices (TiXmlElement *doc, Array< OneD, NekDouble > &dvertx, Array< OneD, NekDouble > &dverty)
 
void EnforceRotationalSymmetry (SpatialDomains::MeshGraphSharedPtr &mesh, Array< OneD, NekDouble > &dvertx, Array< OneD, NekDouble > &dverty)
 
int main (int argc, char *argv[])
 

Enumeration Type Documentation

◆ SolveType

enum SolveType
Enumerator
eSolveX 
eSolveY 
eSolveXY 
eNoSolve 

Definition at line 49 of file MoveMeshToCriticalLayer.cpp.

Function Documentation

◆ EnforceRotationalSymmetry()

void EnforceRotationalSymmetry ( SpatialDomains::MeshGraphSharedPtr mesh,
Array< OneD, NekDouble > &  dvertx,
Array< OneD, NekDouble > &  dverty 
)

Definition at line 687 of file MoveMeshToCriticalLayer.cpp.

690{
691 int i, j;
692 int nverts = mesh->GetNvertices();
693 Array<OneD, NekDouble> x(nverts), y(nverts);
694 NekDouble xval, yval, zval;
695
696 for (i = 0; i < nverts; ++i)
697 {
698 mesh->GetPointGeom(i)->GetCoords(xval, yval, zval);
699 x[i] = xval + dvertx[i];
700 y[i] = yval + dverty[i];
701 }
702
703 NekDouble xmax = Vmath::Vmax(nverts, x, 1);
704 NekDouble tol = 1e-5, dist2, xrot, yrot;
705 Array<OneD, int> index(nverts);
706 // find nearest
707 for (i = 0; i < nverts; ++i)
708 {
709 xrot = -x[i] + xmax;
710 yrot = -y[i];
711 tol = 1.0;
712
713 for (j = 0; j < nverts; ++j)
714 {
715 dist2 =
716 (x[j] - xrot) * (x[j] - xrot) + (y[j] - yrot) * (y[j] - yrot);
717 if (dist2 < tol)
718 {
719 index[i] = j;
720 tol = dist2;
721 }
722 }
723 }
724
725 // average points and recalcualte dvertx, dverty
726 for (i = 0; i < nverts; ++i)
727 {
728 mesh->GetPointGeom(i)->GetCoords(xval, yval, zval);
729
730 xrot = 0.5 * (-x[index[i]] + xmax + x[i]);
731 yrot = 0.5 * (-y[index[i]] + y[i]);
732
733 dvertx[i] = xrot - xval;
734 dverty[i] = yrot - yval;
735 }
736}
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 Vmath::Vmax().

Referenced by main().

◆ GetInterfaceVerts()

void GetInterfaceVerts ( const int  compositeID,
SpatialDomains::MeshGraphSharedPtr mesh,
vector< int > &  InterfaceVerts 
)

Definition at line 162 of file MoveMeshToCriticalLayer.cpp.

165{
167 composite = mesh->GetComposite(compositeID);
168 int compsize = composite->m_geomVec.size();
169 map<int, int> vertmap;
170
171 for (int i = 0; i < compsize; ++i)
172 {
173 if (vertmap.count(composite->m_geomVec[i]->GetVid(0)) == 0)
174 {
175 InterfaceVerts.push_back(composite->m_geomVec[i]->GetVid(0));
176 vertmap[composite->m_geomVec[i]->GetVid(0)] = 1;
177 }
178
179 if (vertmap.count(composite->m_geomVec[i]->GetVid(1)) == 0)
180 {
181 InterfaceVerts.push_back(composite->m_geomVec[i]->GetVid(1));
182 vertmap[composite->m_geomVec[i]->GetVid(1)] = 1;
183 }
184 }
185}
std::shared_ptr< Composite > CompositeSharedPtr
Definition MeshGraph.h:178

Referenced by main().

◆ GetNewVertexLocation()

void GetNewVertexLocation ( TiXmlElement *  doc,
SpatialDomains::MeshGraphSharedPtr mesh,
vector< int > &  InterfaceVerts,
Array< OneD, NekDouble > &  xstreak,
Array< OneD, NekDouble > &  ystreak,
Array< OneD, NekDouble > &  vertx,
Array< OneD, NekDouble > &  verty,
int  maxiter 
)

Definition at line 223 of file MoveMeshToCriticalLayer.cpp.

230{
231 int i, j, k;
232 int nverts = mesh->GetNvertices();
233
234 Array<OneD, MoveVerts> Verts(nverts);
235
236 // loop mesh edges and fill in verts info
239
240 int vid0, vid1;
241 NekDouble kspring;
242 NekDouble x, y, x1, y1, z1, x2, y2, z2;
243
244 // Setup intiial spring and verts
245 for (auto [id, seg] : mesh->GetGeomMap<SpatialDomains::SegGeom>())
246 {
247 vid0 = seg->GetVid(0);
248 vid1 = seg->GetVid(1);
249
250 v0 = seg->GetVertex(0);
251 v1 = seg->GetVertex(1);
252
253 kspring = 1.0 / v0->dist(*v1);
254
255 Verts[vid0].kspring.push_back(kspring);
256 Verts[vid0].springVid.push_back(vid1);
257 Verts[vid1].kspring.push_back(kspring);
258 Verts[vid1].springVid.push_back(vid0);
259 }
260
261 // Scale spring by total around vertex and turn on all vertices.
262 for (i = 0; i < nverts; ++i)
263 {
264 NekDouble invktot = 0.0;
265 for (j = 0; j < Verts[i].kspring.size(); ++j)
266 {
267 invktot += Verts[i].kspring[j];
268 }
269 invktot = 1.0 / invktot;
270 for (j = 0; j < Verts[i].kspring.size(); ++j)
271 {
272 Verts[i].kspring[j] *= invktot;
273 }
274
275 Verts[i].solve = eSolveXY;
276 }
277
278 // Turn off all edges defined by composite lists of correct dimension
279 TurnOffEdges(doc, mesh, Verts);
280
281 NekDouble z, h0, h1, h2;
282 // Set interface vertices to lie on critical layer
283 for (i = 0; i < InterfaceVerts.size(); ++i)
284 {
285 Verts[InterfaceVerts[i]].solve = eNoSolve;
286 mesh->GetPointGeom(InterfaceVerts[i])->GetCoords(x, y, z);
287
288 for (j = 0; j < xstreak.size() - 1; ++j)
289 {
290 if ((x >= xstreak[j]) && (x <= xstreak[j + 1]))
291 {
292 break;
293 }
294 }
295
296 ASSERTL0(j != xstreak.size(),
297 "Did not find x location along critical layer");
298
299 k = (j == 0) ? 1 : j; // offset index at beginning
300
301 // quadraticalling interpolate points
302 h0 =
303 (x - xstreak[k]) * (x - xstreak[k + 1]) /
304 ((xstreak[k - 1] - xstreak[k]) * (xstreak[k - 1] - xstreak[k + 1]));
305 h1 = (x - xstreak[k - 1]) * (x - xstreak[k + 1]) /
306 ((xstreak[k] - xstreak[k - 1]) * (xstreak[k] - xstreak[k + 1]));
307 h2 =
308 (x - xstreak[k - 1]) * (x - xstreak[k]) /
309 ((xstreak[k + 1] - xstreak[k - 1]) * (xstreak[k + 1] - xstreak[k]));
310
311 dvertx[InterfaceVerts[i]] =
312 (xstreak[k - 1] * h0 + xstreak[k] * h1 + xstreak[k + 1] * h2) - x;
313 dverty[InterfaceVerts[i]] =
314 (ystreak[k - 1] * h0 + ystreak[k] * h1 + ystreak[k + 1] * h2) - y;
315 }
316
317 // shift quads in critical layer to move more or less rigidly
318 for (auto [id, quad] : mesh->GetGeomMap<SpatialDomains::QuadGeom>())
319 {
320 for (i = 0; i < 4; ++i)
321 {
322 vid0 = quad->GetVid(i);
323
324 switch (Verts[vid0].solve)
325 {
326 case eSolveXY:
327 {
328 mesh->GetPointGeom(vid0)->GetCoords(x, y, z);
329
330 // find nearest interface vert
331 mesh->GetPointGeom(InterfaceVerts[0])
332 ->GetCoords(x1, y1, z1);
333 for (j = 0; j < InterfaceVerts.size() - 1; ++j)
334 {
335 mesh->GetPointGeom(InterfaceVerts[j + 1])
336 ->GetCoords(x2, y2, z2);
337 if ((x >= x1) && (x < x2))
338 {
339 break;
340 }
341 x1 = x2;
342 y1 = y2;
343 }
344
345 // currently just shift vert as average of two sides
346 dvertx[vid0] =
347 (x2 - x) / (x2 - x1) * dvertx[InterfaceVerts[j]] +
348 (x - x1) / (x2 - x1) * dvertx[InterfaceVerts[j + 1]];
349 dverty[vid0] =
350 (x2 - x) / (x2 - x1) * dverty[InterfaceVerts[j]] +
351 (x - x1) / (x2 - x1) * dverty[InterfaceVerts[j + 1]];
352 }
353 break;
354 case eSolveY:
355 {
356 mesh->GetPointGeom(vid0)->GetCoords(x, y, z);
357 mesh->GetPointGeom(InterfaceVerts[0])
358 ->GetCoords(x1, y1, z1);
359
360 if (fabs(x - x1) < 1e-6)
361 {
362 dverty[vid0] = dverty[InterfaceVerts[0]];
363 }
364 else
365 {
366 dverty[vid0] =
367 dverty[InterfaceVerts[InterfaceVerts.size() - 1]];
368 }
369 }
370 break;
371 default:
372 break;
373 }
374 Verts[vid0].solve = eNoSolve;
375 }
376 }
377
378 // Iterate internal vertices
379 bool ContinueToIterate = true;
380 int cnt = 0;
381 int nsum = 0;
382 NekDouble dsum, dx, dy, sum, prev_sum = 0.0;
383 NekDouble tol = 1e-3, fac;
384 int blend = 50;
385
386 while (ContinueToIterate)
387 {
388
389 sum = 0.0;
390 nsum = 0;
391
392 // use a ramping function to help move interior slowly
393 fac = (cnt < blend) ? 1.0 / (blend + 1.0) * (cnt + 1) : 1.0;
394
395 for (i = 0; i < nverts; ++i)
396 {
397 if (Verts[i].solve != eNoSolve)
398 {
399 dx = dy = 0.0;
400
401 if ((Verts[i].solve == eSolveX) || (Verts[i].solve == eSolveXY))
402 {
403 for (j = 0; j < Verts[i].kspring.size(); ++j)
404 {
405 dx += fac * Verts[i].kspring[j] *
406 dvertx[Verts[i].springVid[j]];
407 }
408 }
409
410 if ((Verts[i].solve == eSolveY) || (Verts[i].solve == eSolveXY))
411 {
412 for (j = 0; j < Verts[i].kspring.size(); ++j)
413 {
414 dy += fac * Verts[i].kspring[j] *
415 dverty[Verts[i].springVid[j]];
416 }
417 }
418
419 dsum = (dx * dx + dy * dy);
420
421 dvertx[i] = dx;
422 dverty[i] = dy;
423
424 if (dsum > 1e-16)
425 {
426 // sum += dsum/(dvertx[i]*dvertx[i] + dverty[i]*dverty[i]);
427 sum += dsum;
428 nsum += 1;
429 }
430 }
431 }
432
433 if (nsum)
434 {
435 sum = sqrt(sum / (NekDouble)nsum);
436
437 NekDouble chg = sum - prev_sum;
438 prev_sum = sum;
439
440 cerr << "Iteration " << cnt << " : " << chg << endl;
441
442 if ((chg < tol) && (cnt > blend))
443 {
444 ContinueToIterate = false;
445 }
446 }
447 else if (cnt > blend)
448 {
449 ContinueToIterate = false;
450 }
451
452 if (cnt++ > maxiter)
453 {
454 ContinueToIterate = false;
455 }
456 }
457}
#define ASSERTL0(condition, msg)
void TurnOffEdges(TiXmlElement *doc, SpatialDomains::MeshGraphSharedPtr &mesh, Array< OneD, MoveVerts > &verts)
int GetVid(int i) const
Returns global id of vertex i of this object.
Definition Geometry.h:353
PointGeom * GetVertex(int i) const
Returns vertex i of this object.
Definition Geometry.h:361
NekDouble dist(PointGeom &a)
return distance between this and input a
std::vector< double > z(NPUPPER)
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290

References ASSERTL0, Nektar::SpatialDomains::PointGeom::dist(), eNoSolve, eSolveX, eSolveXY, eSolveY, Nektar::SpatialDomains::Geometry::GetVertex(), Nektar::SpatialDomains::Geometry::GetVid(), tinysimd::sqrt(), and TurnOffEdges().

Referenced by main().

◆ GetStreakLocation()

void GetStreakLocation ( LibUtilities::SessionReaderSharedPtr vSession,
SpatialDomains::MeshGraphSharedPtr mesh,
string &  fieldfile,
Array< OneD, NekDouble > &  xc,
Array< OneD, NekDouble > &  yc 
)

Definition at line 187 of file MoveMeshToCriticalLayer.cpp.

191{
192 //-------------------------------------------------------------
193 // Define Streak Expansion
195
196 streak =
198 //---------------------------------------------------------------
199
200 //----------------------------------------------
201 // Import field file.
202 vector<LibUtilities::FieldDefinitionsSharedPtr> fielddef;
203 vector<vector<NekDouble>> fielddata;
204 LibUtilities::Import(fieldfile, fielddef, fielddata);
205 //----------------------------------------------
206
207 //----------------------------------------------
208 // Copy data from field file
209 string streak_field("w");
210 for (unsigned int i = 0; i < fielddata.size(); ++i)
211 {
212 streak->ExtractDataToCoeffs(fielddef[i], fielddata[i], streak_field,
213 streak->UpdateCoeffs());
214 }
215 //----------------------------------------------
216
217 NekDouble cr = 0.0;
218
219 cerr << "Extracting Critical Layer ";
220 Computestreakpositions(streak, xc, yc, cr);
221}
void Computestreakpositions(MultiRegions::ExpListSharedPtr &streak, Array< OneD, NekDouble > &xc, Array< OneD, NekDouble > &yc, NekDouble cr, NekDouble trans)
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
void Import(const std::string &infilename, std::vector< FieldDefinitionsSharedPtr > &fielddefs, std::vector< std::vector< NekDouble > > &fielddata, FieldMetaDataMap &fieldinfomap, const Array< OneD, int > &ElementIDs)
This function allows for data to be imported from an FLD file when a session and/or communicator is n...
Definition FieldIO.cpp:287
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr(), Computestreakpositions(), and Nektar::LibUtilities::Import().

Referenced by main().

◆ main()

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

Definition at line 91 of file MoveMeshToCriticalLayer.cpp.

92{
93 if (argc != 4)
94 {
95 fprintf(
96 stderr,
97 "Usage: ./MoveMeshToCriticalLayer meshfile streakfile outfile\n");
98 exit(1);
99 }
100
101 //------------------------------------------------------------
102 // Create Session file by reading only first meshfile
103 //-----------------------------------------------------------
108
109 //-------------------------------------------------------------
110 // Read in mesh from input file
111 //------------------------------------------------------------
112 TiXmlDocument &meshdoc = vSession->GetDocument();
113 TiXmlHandle docHandle(&meshdoc);
114 TiXmlElement *doc = docHandle.FirstChildElement("NEKTAR")
115 .FirstChildElement("GEOMETRY")
116 .Element();
117
118 //------------------------------------------------------------
119 // Get list of vertices along interface
120 //------------------------------------------------------------
121 vector<int> InterfaceVerts;
122 GetInterfaceVerts(300, mesh, InterfaceVerts);
123
124 //------------------------------------------------------------
125 // Determine location of new interface vertices
126 //------------------------------------------------------------
127 Array<OneD, NekDouble> xstreak(50), ystreak(50);
128 string fieldfile(argv[argc - 2]);
129 GetStreakLocation(vSession, mesh, fieldfile, xstreak, ystreak);
130
131 //------------------------------------------------------------
132 // Move internal mesh using critical layer info and under string analogy
133 //------------------------------------------------------------
134 Array<OneD, NekDouble> dvertx(mesh->GetNvertices(), 0.0),
135 dverty(mesh->GetNvertices(), 0.0);
136 int maxiter;
137 vSession->LoadParameter("MoveMeshMaxIterations", maxiter, 100);
138
139 GetNewVertexLocation(doc, mesh, InterfaceVerts, xstreak, ystreak, dvertx,
140 dverty, maxiter);
141
142 //------------------------------------------------------------
143 // Enforce rotational symmetry on mesh
144 //------------------------------------------------------------
145 if (vSession->DefinesSolverInfo("EnforceRotationalSymmetry"))
146 {
147 EnforceRotationalSymmetry(mesh, dvertx, dverty);
148 }
149
150 //------------------------------------------------------------
151 // Redfine vertices in doc
152 //------------------------------------------------------------
153 RedefineVertices(doc, dvertx, dverty);
154
155 //------------------------------------------------------------
156 // Write out moved mesh file
157 //------------------------------------------------------------
158 std::string outfile(argv[argc - 1]);
159 meshdoc.SaveFile(outfile);
160}
void GetNewVertexLocation(TiXmlElement *doc, SpatialDomains::MeshGraphSharedPtr &mesh, vector< int > &InterfaceVerts, Array< OneD, NekDouble > &xstreak, Array< OneD, NekDouble > &ystreak, Array< OneD, NekDouble > &vertx, Array< OneD, NekDouble > &verty, int maxiter)
void EnforceRotationalSymmetry(SpatialDomains::MeshGraphSharedPtr &mesh, Array< OneD, NekDouble > &dvertx, Array< OneD, NekDouble > &dverty)
void RedefineVertices(TiXmlElement *doc, Array< OneD, NekDouble > &dvertx, Array< OneD, NekDouble > &dverty)
void GetInterfaceVerts(const int compositeID, SpatialDomains::MeshGraphSharedPtr &mesh, vector< int > &InterfaceVerts)
void GetStreakLocation(LibUtilities::SessionReaderSharedPtr &vSession, SpatialDomains::MeshGraphSharedPtr &mesh, string &fieldfile, Array< OneD, NekDouble > &xc, Array< OneD, NekDouble > &yc)
static SessionReaderSharedPtr CreateInstance(int argc, char *argv[])
Creates an instance of the SessionReader class.
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< MeshGraph > MeshGraphSharedPtr
Definition MeshGraph.h:217

References Nektar::LibUtilities::SessionReader::CreateInstance(), EnforceRotationalSymmetry(), GetInterfaceVerts(), GetNewVertexLocation(), GetStreakLocation(), Nektar::SpatialDomains::MeshGraphIO::Read(), and RedefineVertices().

◆ RedefineVertices()

void RedefineVertices ( TiXmlElement *  doc,
Array< OneD, NekDouble > &  dvertx,
Array< OneD, NekDouble > &  dverty 
)

Error value returned by TinyXML.

Definition at line 614 of file MoveMeshToCriticalLayer.cpp.

616{
617
618 TiXmlElement *element = doc->FirstChildElement("VERTEX");
619 ASSERTL0(element, "Unable to find mesh VERTEX tag in file.");
620
621 TiXmlElement *vertex = element->FirstChildElement("V");
622
623 int indx;
624 int err; /// Error value returned by TinyXML.
625
626 vector<NekDouble> xpts, ypts, zpts;
627 NekDouble xval, yval, zval;
628
629 while (vertex)
630 {
631 TiXmlAttribute *vertexAttr = vertex->FirstAttribute();
632 std::string attrName(vertexAttr->Name());
633
634 ASSERTL0(attrName == "ID",
635 (std::string("Unknown attribute name: ") + attrName).c_str());
636
637 err = vertexAttr->QueryIntValue(&indx);
638 ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
639
640 // Now read body of vertex
641 std::string vertexBodyStr;
642
643 TiXmlNode *vertexBody = vertex->FirstChild();
644
645 while (vertexBody)
646 {
647 // Accumulate all non-comment body data.
648 if (vertexBody->Type() == TiXmlNode::TINYXML_TEXT)
649 {
650 vertexBodyStr += vertexBody->ToText()->Value();
651 vertexBodyStr += " ";
652 }
653
654 vertexBody = vertexBody->NextSibling();
655 }
656
657 ASSERTL0(!vertexBodyStr.empty(),
658 "Vertex definitions must contain vertex data.");
659
660 // Get vertex data from the data string.
661 std::istringstream vertexDataStrm(vertexBodyStr.c_str());
662
663 try
664 {
665 while (!vertexDataStrm.fail())
666 {
667 vertexDataStrm >> xval >> yval >> zval;
668 }
669
670 xval += dvertx[indx];
671 yval += dverty[indx];
672
673 stringstream s;
674 s << scientific << setprecision(8) << xval << " " << yval << " "
675 << zval;
676
677 vertex->ReplaceChild(vertex->FirstChild(), TiXmlText(s.str()));
678 }
679 catch (...)
680 {
681 ASSERTL0(false, "Unable to read VERTEX data.");
682 }
683 vertex = vertex->NextSiblingElement("V");
684 }
685}

References ASSERTL0.

Referenced by main().

◆ TurnOffEdges()

void TurnOffEdges ( TiXmlElement *  doc,
SpatialDomains::MeshGraphSharedPtr mesh,
Array< OneD, MoveVerts > &  verts 
)

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 461 of file MoveMeshToCriticalLayer.cpp.

463{
464 TiXmlElement *field = doc->FirstChildElement("COMPOSITE");
465 ASSERTL0(field, "Unable to find COMPOSITE tag in file.");
466
467 /// All elements are of the form: "<C ID = "N"> ... </C>".
468 /// Read the ID field first.
469 TiXmlElement *composite = field->FirstChildElement("C");
470
471 while (composite)
472 {
473 int indx;
474 int err = composite->QueryIntAttribute("ID", &indx);
475 ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
476
477 TiXmlNode *compositeChild = composite->FirstChild();
478 // This is primarily to skip comments that may be present.
479 // Comments appear as nodes just like elements.
480 // We are specifically looking for text in the body
481 // of the definition.
482 while (compositeChild &&
483 compositeChild->Type() != TiXmlNode::TINYXML_TEXT)
484 {
485 compositeChild = compositeChild->NextSibling();
486 }
487
488 ASSERTL0(compositeChild, "Unable to read composite definition body.");
489 std::string compositeStr = compositeChild->ToText()->ValueStr();
490
491 /// Parse out the element components corresponding to type of element.
492 std::istringstream compositeDataStrm(compositeStr.c_str());
493
494 try
495 {
496 std::string compositeElementStr;
497 compositeDataStrm >> compositeElementStr;
498
499 std::istringstream tokenStream(compositeElementStr);
500 char type;
501
502 tokenStream >> type;
503
504 // in what follows we are assuming there is only one block of data
505 std::string::size_type indxBeg =
506 compositeElementStr.find_first_of('[') + 1;
507 std::string::size_type indxEnd =
508 compositeElementStr.find_last_of(']') - 1;
509
510 ASSERTL0(indxBeg <= indxEnd,
511 (std::string("Error reading index definition:") +
512 compositeElementStr)
513 .c_str());
514
515 std::string indxStr =
516 compositeElementStr.substr(indxBeg, indxEnd - indxBeg + 1);
517 std::vector<unsigned int> seqVector;
518
519 bool err = ParseUtils::GenerateSeqVector(indxStr, seqVector);
520
521 ASSERTL0(err, (std::string("Error reading composite elements: ") +
522 indxStr)
523 .c_str());
524
525 switch (type)
526 {
527 case 'E': // Turn off vertices along composite edges
528 {
529 int seqlen = seqVector.size();
530 NekDouble x0, y0, z0, x1, y1, z1;
531 int vid0, vid1;
532
533 for (int i = 0; i < seqlen; ++i)
534 {
535 auto seg = mesh->GetSegGeom(seqVector[i]);
536 seg->GetVertex(0)->GetCoords(x0, y0, z0);
537 seg->GetVertex(1)->GetCoords(x1, y1, z1);
538 vid0 = seg->GetVid(0);
539 vid1 = seg->GetVid(1);
540
541 if (fabs(x0 - x1) < 1e-8)
542 {
543 // identify corners by double visit
544 if (Verts[vid0].solve == eSolveX)
545 {
546 Verts[vid0].solve = eNoSolve;
547 }
548 else
549 {
550 Verts[vid0].solve = eSolveY;
551 }
552
553 if (Verts[vid1].solve == eSolveX)
554 {
555 Verts[vid1].solve = eNoSolve;
556 }
557 else
558 {
559 Verts[vid1].solve = eSolveY;
560 }
561 }
562
563 if (fabs(y0 - y1) < 1e-8)
564 {
565 // identify corners by double visit
566 if (Verts[vid0].solve == eSolveY)
567 {
568 Verts[vid0].solve = eNoSolve;
569 }
570 else
571 {
572 Verts[vid0].solve = eSolveX;
573 }
574
575 if (Verts[vid1].solve == eSolveY)
576 {
577 Verts[vid1].solve = eNoSolve;
578 }
579 else
580 {
581 Verts[vid1].solve = eSolveX;
582 }
583 }
584 }
585 }
586 break;
587
588 case 'T':
589 case 'Q': // do nothing
590 {
591 break;
592 }
593 default:
595 (std::string("Unrecognized composite token: ") +
596 compositeElementStr)
597 .c_str());
598 }
599 }
600 catch (...)
601 {
602 NEKERROR(
604 (std::string("Unable to read COMPOSITE data for composite: ") +
605 compositeStr)
606 .c_str());
607 }
608
609 /// Keep looking
610 composite = composite->NextSiblingElement("C");
611 }
612}
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
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, eNoSolve, eSolveX, eSolveY, Nektar::ParseUtils::GenerateSeqVector(), and NEKERROR.

Referenced by GetNewVertexLocation().