Nektar++
Classes | Enumerations | Functions
MoveMeshToCriticalLayer.cpp File Reference
#include <cstdio>
#include <cstdlib>
#include <iomanip>
#include <tinyxml.h>
#include <SpatialDomains/MeshGraph.h>
#include <MultiRegions/ExpList.h>
#include <MultiRegions/ExpList2D.h>
#include <LibUtilities/BasicUtils/ParseUtils.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::SegGeomMap &meshedges, 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 50 of file MoveMeshToCriticalLayer.cpp.

Function Documentation

◆ EnforceRotationalSymmetry()

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

Definition at line 678 of file MoveMeshToCriticalLayer.cpp.

References Vmath::Vmax().

Referenced by main().

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

◆ GetInterfaceVerts()

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

Definition at line 160 of file MoveMeshToCriticalLayer.cpp.

Referenced by main().

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

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

References ASSERTL0, Nektar::SpatialDomains::PointGeom::dist(), eNoSolve, eSolveX, eSolveXY, eSolveY, and TurnOffEdges().

Referenced by main().

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

◆ GetStreakLocation()

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

Definition at line 183 of file MoveMeshToCriticalLayer.cpp.

References Computestreakpositions(), and Nektar::LibUtilities::Import().

Referenced by main().

186 {
187  //-------------------------------------------------------------
188  // Define Streak Expansion
190 
192  ::AllocateSharedPtr(vSession,mesh);
193  //---------------------------------------------------------------
194 
195  //----------------------------------------------
196  // Import field file.
197  vector<LibUtilities::FieldDefinitionsSharedPtr> fielddef;
198  vector<vector<NekDouble> > fielddata;
199  LibUtilities::Import(fieldfile,fielddef,fielddata);
200  //----------------------------------------------
201 
202  //----------------------------------------------
203  // Copy data from field file
204  string streak_field("w");
205  for(unsigned int i = 0; i < fielddata.size(); ++i)
206  {
207  streak->ExtractDataToCoeffs(fielddef [i],
208  fielddata[i],
209  streak_field,
210  streak->UpdateCoeffs());
211  }
212  //----------------------------------------------
213 
214  NekDouble cr = 0.0;
215 
216  cerr << "Extracting Critical Layer ";
217  Computestreakpositions(streak,xc, yc,cr);
218 }
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
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:274
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
void Computestreakpositions(MultiRegions::ExpListSharedPtr &streak, Array< OneD, NekDouble > &xc, Array< OneD, NekDouble > &yc, NekDouble cr, NekDouble trans)
double NekDouble

◆ main()

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

Definition at line 94 of file MoveMeshToCriticalLayer.cpp.

References EnforceRotationalSymmetry(), GetInterfaceVerts(), GetNewVertexLocation(), GetStreakLocation(), and RedefineVertices().

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

◆ RedefineVertices()

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

Error value returned by TinyXML.

Definition at line 601 of file MoveMeshToCriticalLayer.cpp.

References ASSERTL0.

Referenced by main().

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

◆ TurnOffEdges()

void TurnOffEdges ( TiXmlElement *  doc,
SpatialDomains::SegGeomMap meshedges,
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 458 of file MoveMeshToCriticalLayer.cpp.

References ASSERTL0, eNoSolve, eSolveX, eSolveY, and NEKERROR.

Referenced by GetNewVertexLocation().

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