Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MeshGraph2D.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////
2 // File: MeshGraph2D.cpp
3 //
4 // For more information, please see: http://www.nektar.info/
5 //
6 // The MIT License
7 //
8 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
9 // Department of Aeronautics, Imperial College London (UK), and Scientific
10 // Computing and Imaging Institute, University of Utah (USA).
11 //
12 // License for the specific language governing rights and limitations under
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description:
32 //
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
37 #include <SpatialDomains/SegGeom.h>
38 #include <SpatialDomains/TriGeom.h>
41 #include <tinyxml.h>
42 
43 using namespace std;
44 
45 namespace Nektar
46 {
47  namespace SpatialDomains
48  {
49  MeshGraph2D::MeshGraph2D()
50  {
51  }
52 
53  MeshGraph2D::~MeshGraph2D()
54  {
55  }
56 
57  MeshGraph2D::MeshGraph2D(const LibUtilities::SessionReaderSharedPtr &pSession,
58  const DomainRangeShPtr &rng)
59  : MeshGraph(pSession,rng)
60  {
61  ReadGeometry(pSession->GetDocument());
62  ReadExpansions(pSession->GetDocument());
63  }
64 
65  void MeshGraph2D::ReadGeometry(const std::string &infilename)
66  {
67  TiXmlDocument doc(infilename);
68  bool loadOkay = doc.LoadFile();
69 
70  std::stringstream errstr;
71  errstr << "Unable to load file: " << infilename << "\n";
72  errstr << doc.ErrorDesc() << " (Line " << doc.ErrorRow()
73  << ", Column " << doc.ErrorCol() << ")";
74  ASSERTL0(loadOkay, errstr.str());
75 
76  ReadGeometry(doc);
77  }
78 
79  // \brief Read segments (and general MeshGraph) given TiXmlDocument.
80  void MeshGraph2D::ReadGeometry(TiXmlDocument &doc)
81  {
82  // Read mesh first
84  TiXmlHandle docHandle(&doc);
85 
86  TiXmlElement* mesh = NULL;
87 
88  /// Look for all geometry related data in GEOMETRY block.
89  mesh = docHandle.FirstChildElement("NEKTAR").FirstChildElement("GEOMETRY").Element();
90 
91  ASSERTL0(mesh, "Unable to find GEOMETRY tag in file.");
92 
93  ReadCurves(doc);
94  ReadEdges(doc);
95  ReadElements(doc);
96  ReadComposites(doc);
97  ReadDomain(doc);
98  }
99 
100  void MeshGraph2D::ReadEdges(TiXmlDocument &doc)
101  {
102  /// We know we have it since we made it this far.
103  TiXmlHandle docHandle(&doc);
104  TiXmlElement* mesh = docHandle.FirstChildElement("NEKTAR").FirstChildElement("GEOMETRY").Element();
105  TiXmlElement* field = NULL;
107 
108  /// Look for elements in ELEMENT block.
109  field = mesh->FirstChildElement("EDGE");
110 
111  ASSERTL0(field, "Unable to find EDGE tag in file.");
112 
113  string IsCompressed;
114  field->QueryStringAttribute("COMPRESSED",&IsCompressed);
115 
116  if(IsCompressed.size())
117  {
118  ASSERTL0(boost::iequals(IsCompressed,
120  "Compressed formats do not match. Expected :"
122  + " but got " + std::string(IsCompressed));
123 
124  // Extract the edge body
125  TiXmlNode* edgeChild = field->FirstChild();
126  ASSERTL0(edgeChild, "Unable to extract the data from "
127  "the compressed edge tag.");
128 
129  std::string edgeStr;
130  if (edgeChild->Type() == TiXmlNode::TINYXML_TEXT)
131  {
132  edgeStr += edgeChild->ToText()->ValueStr();
133  }
134 
135  std::vector<LibUtilities::MeshEdge> edgeData;
137  edgeData);
138  int indx;
139  for(int i = 0; i < edgeData.size(); ++i)
140  {
141  indx = edgeData[i].id;
142 
143  PointGeomSharedPtr vertices[2] =
144  {GetVertex(edgeData[i].v0), GetVertex(edgeData[i].v1)};
145  SegGeomSharedPtr edge;
146 
147  it = m_curvedEdges.find(indx);
148  if (it == m_curvedEdges.end())
149  {
151  indx, m_spaceDimension, vertices);
152  }
153  else
154  {
156  indx, m_spaceDimension, vertices,
157  it->second);
158  }
159  m_segGeoms[indx] = edge;
160  }
161  }
162  else
163  {
164  /// All elements are of the form: "<E ID="#"> ... </E>", with
165  /// ? being the element type.
166  /// Read the ID field first.
167  TiXmlElement *edge = field->FirstChildElement("E");
168 
169  /// Since all edge data is one big text block, we need to
170  /// accumulate all TINYXML_TEXT data and then parse it. This
171  /// approach effectively skips all comments or other node
172  /// types since we only care about the edge list. We
173  /// cannot handle missing edge numbers as we could with
174  /// missing element numbers due to the text block format.
175  std::string edgeStr;
176  int indx;
177 
178  while(edge)
179  {
180  int err = edge->QueryIntAttribute("ID",&indx);
181  ASSERTL0(err == TIXML_SUCCESS, "Unable to read edge attribute ID.");
182 
183  TiXmlNode *child = edge->FirstChild();
184  edgeStr.clear();
185  if (child->Type() == TiXmlNode::TINYXML_TEXT)
186  {
187  edgeStr += child->ToText()->ValueStr();
188  }
189 
190  /// Now parse out the edges, three fields at a time.
191  int vertex1, vertex2;
192  std::istringstream edgeDataStrm(edgeStr.c_str());
193 
194  try
195  {
196  while (!edgeDataStrm.fail())
197  {
198  edgeDataStrm >> vertex1 >> vertex2;
199 
200  // Must check after the read because we may be
201  // at the end and not know it. If we are at
202  // the end we will add a duplicate of the last
203  // entry if we don't check here.
204  if (!edgeDataStrm.fail())
205  {
206  PointGeomSharedPtr vertices[2] = {GetVertex(vertex1), GetVertex(vertex2)};
207 
208  SegGeomSharedPtr edge;
209 
210  it = m_curvedEdges.find(indx);
211 
212  if(it == m_curvedEdges.end())
213  {
215  edge->SetGlobalID(indx); // Set global mesh id
216  }
217  else
218  {
219  edge = MemoryManager<SegGeom>::AllocateSharedPtr(indx, m_spaceDimension, vertices, it->second);
220  edge->SetGlobalID(indx); //Set global mesh id
221  }
222 
223  m_segGeoms[indx] = edge;
224  }
225  }
226  }
227  catch(...)
228  {
229  NEKERROR(ErrorUtil::efatal, (std::string("Unable to read edge data: ") + edgeStr).c_str());
230  }
231 
232  edge = edge->NextSiblingElement("E");
233  }
234  }
235  }
236 
237  void MeshGraph2D::ReadElements(TiXmlDocument &doc)
238  {
239  /// We know we have it since we made it this far.
240  TiXmlHandle docHandle(&doc);
241  TiXmlElement* mesh = docHandle.FirstChildElement("NEKTAR").FirstChildElement("GEOMETRY").Element();
242  TiXmlElement* field = NULL;
243 
244  /// Look for elements in ELEMENT block.
245  field = mesh->FirstChildElement("ELEMENT");
246 
247  ASSERTL0(field, "Unable to find ELEMENT tag in file.");
248 
249  // Set up curve map for curved elements on an embedded manifold.
251 
252  /// All elements are of the form: "<? ID="#"> ... </?>", with
253  /// ? being the element type.
254 
255  TiXmlElement *element = field->FirstChildElement();
256 
257  while (element)
258  {
259  std::string elementType(element->ValueStr());
260 
261  ASSERTL0(elementType == "Q" || elementType == "T",
262  (std::string("Unknown 2D element type: ") + elementType).c_str());
263 
264  string IsCompressed;
265  element->QueryStringAttribute("COMPRESSED",&IsCompressed);
266 
267  if(IsCompressed.size())
268  {
269  ASSERTL0(boost::iequals(IsCompressed,
271  "Compressed formats do not match. Expected :"
273  + " but got " + std::string(IsCompressed));
274 
275  // Extract the face body
276  TiXmlNode* faceChild = element->FirstChild();
277  ASSERTL0(faceChild, "Unable to extract the data from "
278  "the compressed face tag.");
279 
280  std::string faceStr;
281  if (faceChild->Type() == TiXmlNode::TINYXML_TEXT)
282  {
283  faceStr += faceChild->ToText()->ValueStr();
284  }
285 
286  int indx;
287  if(elementType == "T")
288  {
289  std::vector<LibUtilities::MeshTri> faceData;
291  faceStr, faceData);
292 
293  for(int i = 0; i < faceData.size(); ++i)
294  {
295  indx = faceData[i].id;
296 
297  /// See if this face has curves.
298  it = m_curvedFaces.find(indx);
299 
300  /// Create a TriGeom to hold the new definition.
302  {
303  GetSegGeom(faceData[i].e[0]),
304  GetSegGeom(faceData[i].e[1]),
305  GetSegGeom(faceData[i].e[2])
306  };
307 
309  {
310  SegGeom::GetEdgeOrientation(*edges[0], *edges[1]),
311  SegGeom::GetEdgeOrientation(*edges[1], *edges[2]),
312  SegGeom::GetEdgeOrientation(*edges[2], *edges[0])
313  };
314 
315  TriGeomSharedPtr trigeom;
316  if (it == m_curvedFaces.end())
317  {
318  trigeom =
320  indx, edges, edgeorient);
321  }
322  else
323  {
324  trigeom =
326  indx, edges, edgeorient,
327  it->second);
328  }
329  trigeom->SetGlobalID(indx);
330  m_triGeoms[indx] = trigeom;
331  }
332  }
333  else if (elementType == "Q")
334  {
335  std::vector<LibUtilities::MeshQuad> faceData;
337  faceStr,faceData);
338 
339  for(int i = 0; i < faceData.size(); ++i)
340  {
341  indx = faceData[i].id;
342 
343  /// See if this face has curves.
344  it = m_curvedFaces.find(indx);
345 
346  /// Create a QuadGeom to hold the new definition.
348  {GetSegGeom(faceData[i].e[0]),
349  GetSegGeom(faceData[i].e[1]),
350  GetSegGeom(faceData[i].e[2]),
351  GetSegGeom(faceData[i].e[3])};
352 
354  {
355  SegGeom::GetEdgeOrientation(*edges[0], *edges[1]),
356  SegGeom::GetEdgeOrientation(*edges[1], *edges[2]),
357  SegGeom::GetEdgeOrientation(*edges[2], *edges[3]),
358  SegGeom::GetEdgeOrientation(*edges[3], *edges[0])
359  };
360 
361  QuadGeomSharedPtr quadgeom;
362  if (it == m_curvedEdges.end())
363  {
364  quadgeom =
366  indx, edges, edgeorient);
367  }
368  else
369  {
370  quadgeom =
372  indx, edges, edgeorient,
373  it->second);
374  }
375  quadgeom->SetGlobalID(indx);
376  m_quadGeoms[indx] = quadgeom;
377  }
378  }
379  }
380  else
381  {
382  /// Read id attribute.
383  int indx;
384  int err = element->QueryIntAttribute("ID", &indx);
385  ASSERTL0(err == TIXML_SUCCESS, "Unable to read element attribute ID.");
386 
387  it = m_curvedFaces.find(indx);
388 
389  /// Read text element description.
390  TiXmlNode* elementChild = element->FirstChild();
391  std::string elementStr;
392  while(elementChild)
393  {
394  if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
395  {
396  elementStr += elementChild->ToText()->ValueStr();
397  }
398  elementChild = elementChild->NextSibling();
399  }
400 
401  ASSERTL0(!elementStr.empty(), "Unable to read element description body.");
402 
403  /// Parse out the element components corresponding to type of element.
404  if (elementType == "T")
405  {
406  // Read three edge numbers
407  int edge1, edge2, edge3;
408  std::istringstream elementDataStrm(elementStr.c_str());
409 
410  try
411  {
412  elementDataStrm >> edge1;
413  elementDataStrm >> edge2;
414  elementDataStrm >> edge3;
415 
416  ASSERTL0(!elementDataStrm.fail(), (std::string("Unable to read element data for TRIANGLE: ") + elementStr).c_str());
417 
418  /// Create a TriGeom to hold the new definition.
420  {
421  GetSegGeom(edge1),
422  GetSegGeom(edge2),
423  GetSegGeom(edge3)
424  };
425 
427  {
428  SegGeom::GetEdgeOrientation(*edges[0], *edges[1]),
429  SegGeom::GetEdgeOrientation(*edges[1], *edges[2]),
430  SegGeom::GetEdgeOrientation(*edges[2], *edges[0])
431  };
432 
433  TriGeomSharedPtr trigeom;
434  if (it == m_curvedFaces.end())
435  {
436  trigeom = MemoryManager<TriGeom>
438  edges,
439  edgeorient);
440  }
441  else
442  {
443  trigeom = MemoryManager<TriGeom>
445  edges,
446  edgeorient,
447  it->second);
448  }
449  trigeom->SetGlobalID(indx);
450 
451  m_triGeoms[indx] = trigeom;
452  }
453  catch(...)
454  {
455  NEKERROR(ErrorUtil::efatal, (std::string("Unable to read element data for TRIANGLE: ") + elementStr).c_str());
456  }
457  }
458  else if (elementType == "Q")
459  {
460  // Read four edge numbers
461  int edge1, edge2, edge3, edge4;
462  std::istringstream elementDataStrm(elementStr.c_str());
463 
464  try
465  {
466  elementDataStrm >> edge1;
467  elementDataStrm >> edge2;
468  elementDataStrm >> edge3;
469  elementDataStrm >> edge4;
470 
471  ASSERTL0(!elementDataStrm.fail(), (std::string("Unable to read element data for QUAD: ") + elementStr).c_str());
472 
473  /// Create a QuadGeom to hold the new definition.
475  {GetSegGeom(edge1),GetSegGeom(edge2),
476  GetSegGeom(edge3),GetSegGeom(edge4)};
477 
479  {
480  SegGeom::GetEdgeOrientation(*edges[0], *edges[1]),
481  SegGeom::GetEdgeOrientation(*edges[1], *edges[2]),
482  SegGeom::GetEdgeOrientation(*edges[2], *edges[3]),
483  SegGeom::GetEdgeOrientation(*edges[3], *edges[0])
484  };
485 
486  QuadGeomSharedPtr quadgeom;
487  if (it == m_curvedFaces.end())
488  {
489  quadgeom = MemoryManager<QuadGeom>
491  edges,
492  edgeorient);
493  }
494  else
495  {
496  quadgeom = MemoryManager<QuadGeom>
498  edges,
499  edgeorient,
500  it->second);
501  }
502  quadgeom->SetGlobalID(indx);
503 
504  m_quadGeoms[indx] = quadgeom;
505 
506  }
507  catch(...)
508  {
509  NEKERROR(ErrorUtil::efatal,(std::string("Unable to read element data for QUAD: ") + elementStr).c_str());
510  }
511  }
512  }
513  /// Keep looking
514  element = element->NextSiblingElement();
515  }
516  }
517 
518  void MeshGraph2D::ReadComposites(TiXmlDocument &doc)
519  {
520  TiXmlHandle docHandle(&doc);
521 
522  /// We know we have it since we made it this far.
523  TiXmlElement* mesh = docHandle.FirstChildElement("NEKTAR").FirstChildElement("GEOMETRY").Element();
524  TiXmlElement* field = NULL;
525 
526  ASSERTL0(mesh, "Unable to find GEOMETRY tag in file.");
527 
528  /// Look for elements in ELEMENT block.
529  field = mesh->FirstChildElement("COMPOSITE");
530 
531  ASSERTL0(field, "Unable to find COMPOSITE tag in file.");
532 
533  int nextCompositeNumber = -1;
534 
535  /// All elements are of the form: "<C ID = "N"> ... </C>".
536  /// Read the ID field first.
537  TiXmlElement *composite = field->FirstChildElement("C");
538 
539  while (composite)
540  {
541  nextCompositeNumber++;
542 
543  int indx;
544  int err = composite->QueryIntAttribute("ID", &indx);
545  ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
546 
547  // read and store label if they exist
548  string labelstr;
549  err = composite->QueryStringAttribute("LABEL", &labelstr);
550  if(err == TIXML_SUCCESS)
551  {
552  m_compositesLabels[indx] = labelstr;
553  }
554 
555  TiXmlNode* compositeChild = composite->FirstChild();
556  // This is primarily to skip comments that may be present.
557  // Comments appear as nodes just like elements.
558  // We are specifically looking for text in the body
559  // of the definition.
560  while(compositeChild && compositeChild->Type() != TiXmlNode::TINYXML_TEXT)
561  {
562  compositeChild = compositeChild->NextSibling();
563  }
564 
565  ASSERTL0(compositeChild, "Unable to read composite definition body.");
566  std::string compositeStr = compositeChild->ToText()->ValueStr();
567 
568  /// Parse out the element components corresponding to type of element.
569 
570  std::istringstream compositeDataStrm(compositeStr.c_str());
571 
572  try
573  {
574  bool first = true;
575  std::string prevCompositeElementStr;
576 
577  while (!compositeDataStrm.fail())
578  {
579  std::string compositeElementStr;
580  compositeDataStrm >> compositeElementStr;
581 
582  if (!compositeDataStrm.fail())
583  {
584  if (first)
585  {
586  first = false;
587 
589  m_meshComposites[indx] = curVector;
590  }
591 
592  if (compositeElementStr.length() > 0)
593  {
594  ResolveGeomRef(prevCompositeElementStr, compositeElementStr, m_meshComposites[indx]);
595  }
596  prevCompositeElementStr = compositeElementStr;
597  }
598  }
599  }
600  catch(...)
601  {
603  (std::string("Unable to read COMPOSITE data for composite: ") + compositeStr).c_str());
604  }
605 
606  /// Keep looking
607  composite = composite->NextSiblingElement("C");
608  }
609  }
610 
611 
613  {
614  SegGeomSharedPtr returnval;
615  SegGeomMap::iterator x = m_segGeoms.find(eID);
616  ASSERTL0(x != m_segGeoms.end(), "Segment not found.");
617  return x->second;
618  };
619 
620 
621  // Take the string that is the composite reference and find the
622  // pointer to the Geometry object corresponding to it.
623 
624  // The only allowable combinations of previous and current items
625  // are V (0D); E (1D); and T and Q (2D). Only elements of the same
626  // dimension are allowed to be grouped.
627  void MeshGraph2D::ResolveGeomRef(const std::string &prevToken, const std::string &token,
628  Composite& composite)
629  {
630  try
631  {
632  std::istringstream tokenStream(token);
633  std::istringstream prevTokenStream(prevToken);
634 
635  char type;
636  char prevType;
637 
638  tokenStream >> type;
639 
640  std::string::size_type indxBeg = token.find_first_of('[') + 1;
641  std::string::size_type indxEnd = token.find_last_of(']') - 1;
642 
643  ASSERTL0(indxBeg <= indxEnd, (std::string("Error reading index definition:") + token).c_str());
644 
645  std::string indxStr = token.substr(indxBeg, indxEnd - indxBeg + 1);
646  std::vector<unsigned int> seqVector;
648 
649  bool err = ParseUtils::GenerateSeqVector(indxStr.c_str(), seqVector);
650 
651  ASSERTL0(err, (std::string("Error reading composite elements: ") + indxStr).c_str());
652 
653  prevTokenStream >> prevType;
654 
655  // All composites must be of the same dimension.
656  bool validSequence = (prevToken.empty() || // No previous, then current is just fine.
657  (type == 'V' && prevType == 'V') ||
658  (type == 'E' && prevType == 'E') ||
659  ((type == 'T' || type == 'Q') &&
660  (prevType == 'T' || prevType == 'Q')));
661 
662  ASSERTL0(validSequence, (std::string("Invalid combination of composite items: ")
663  + type + " and " + prevType + ".").c_str());
664 
665 
666  switch(type)
667  {
668  case 'E': // Edge
669  for (seqIter = seqVector.begin(); seqIter != seqVector.end(); ++seqIter)
670  {
671  if (m_segGeoms.find(*seqIter) == m_segGeoms.end())
672  {
673  char errStr[16] = "";
674  ::sprintf(errStr, "%d", *seqIter);
675  NEKERROR(ErrorUtil::ewarning, (std::string("Unknown edge index: ") + errStr).c_str());
676  }
677  else
678  {
679  composite->push_back(m_segGeoms[*seqIter]);
680  }
681  }
682  break;
683 
684  case 'T': // Triangle
685  {
686  for (seqIter = seqVector.begin(); seqIter != seqVector.end(); ++seqIter)
687  {
688  if (m_triGeoms.count(*seqIter) == 0 )
689  {
690  char errStr[16] = "";
691  ::sprintf(errStr, "%d", *seqIter);
692  NEKERROR(ErrorUtil::ewarning, (std::string("Unknown triangle index: ") + errStr).c_str());
693  }
694  else
695  {
696  if(CheckRange(*m_triGeoms[*seqIter]))
697  {
698  composite->push_back(m_triGeoms[*seqIter]);
699  }
700  }
701  }
702  }
703  break;
704 
705  case 'Q': // Quad
706  {
707  for (seqIter = seqVector.begin(); seqIter != seqVector.end(); ++seqIter)
708  {
709  if (m_quadGeoms.count(*seqIter) == 0)
710  {
711  char errStr[16] = "";
712  ::sprintf(errStr, "%d", *seqIter);
713  NEKERROR(ErrorUtil::ewarning, (std::string("Unknown quad index: ") + errStr +std::string(" in Composite section")).c_str());
714  }
715  else
716  {
717  if(CheckRange(*m_quadGeoms[*seqIter]))
718  {
719  composite->push_back(m_quadGeoms[*seqIter]);
720  }
721  }
722  }
723  }
724  break;
725 
726  case 'V': // Vertex
727  for (seqIter = seqVector.begin(); seqIter != seqVector.end(); ++seqIter)
728  {
729  if (*seqIter >= m_vertSet.size())
730  {
731  char errStr[16] = "";
732  ::sprintf(errStr, "%d", *seqIter);
733  NEKERROR(ErrorUtil::ewarning, (std::string("Unknown vertex index: ") + errStr).c_str());
734  }
735  else
736  {
737  composite->push_back(m_vertSet[*seqIter]);
738  }
739  }
740  break;
741 
742  default:
743  NEKERROR(ErrorUtil::efatal, (std::string("Unrecognized composite token: ") + token).c_str());
744  }
745  }
746  catch(...)
747  {
748  NEKERROR(ErrorUtil::efatal, (std::string("Problem processing composite token: ") + token).c_str());
749  }
750 
751  return;
752  }
753 
755  {
756  SegGeomSharedPtr Sedge;
757 
758  if(!(Sedge = boost::dynamic_pointer_cast<SegGeom>(edge)))
759  {
760  ASSERTL0(false,"Dynamics cast failed");
761 
762  }
763  return GetElementsFromEdge(Sedge);
764 
765  }
767  {
768  // Search tris and quads
769  // Need to iterate through vectors because there may be multiple
770  // occurrences.
771  ElementEdgeSharedPtr elementEdge;
772  //TriGeomVectorIter triIter;
773 
775 
776  CompositeMapIter compIter;
777  TriGeomSharedPtr triGeomShPtr;
778  QuadGeomSharedPtr quadGeomShPtr;
779 
780  GeometryVectorIter geomIter;
781 
782  for(int d = 0; d < m_domain.size(); ++d)
783  {
784  for (compIter = m_domain[d].begin(); compIter != m_domain[d].end(); ++compIter)
785  {
786  for (geomIter = (compIter->second)->begin(); geomIter != (compIter->second)->end(); ++geomIter)
787  {
788  triGeomShPtr = boost::dynamic_pointer_cast<TriGeom>(*geomIter);
789  quadGeomShPtr = boost::dynamic_pointer_cast<QuadGeom>(*geomIter);
790 
791  if (triGeomShPtr || quadGeomShPtr)
792  {
793  int edgeNum;
794  if (triGeomShPtr)
795  {
796  if ((edgeNum = triGeomShPtr->WhichEdge(edge)) > -1)
797  {
799  elementEdge->m_Element = triGeomShPtr;
800  elementEdge->m_EdgeIndx = edgeNum;
801  returnval->push_back(elementEdge);
802  }
803  }
804  else if (quadGeomShPtr)
805  {
806  if ((edgeNum = quadGeomShPtr->WhichEdge(edge)) > -1)
807  {
809  elementEdge->m_Element = quadGeomShPtr;
810  elementEdge->m_EdgeIndx = edgeNum;
811  returnval->push_back(elementEdge);
812  }
813  }
814  }
815  }
816  }
817  }
818 
819  return returnval;
820  }
821 
823  {
825  // Perhaps, a check should be done here to ensure that
826  // in case elements->size!=1, all elements to which
827  // the edge belongs have the same type and order of
828  // expansion such that no confusion can arise.
829  ExpansionShPtr expansion = GetExpansion((*elements)[0]->m_Element, variable);
830 
831  int edge_id = (*elements)[0]->m_EdgeIndx;
832 
833  if((*elements)[0]->m_Element->GetShapeType() == LibUtilities::eTriangle)
834  {
835  edge_id = (edge_id)? 1:0;
836  }
837  else
838  {
839  edge_id = edge_id%2;
840  }
841 
842  int nummodes = expansion->m_basisKeyVector[edge_id].GetNumModes();
843  int numpoints = expansion->m_basisKeyVector[edge_id].GetNumPoints();
844 
845  if((*elements)[0]->m_Element->GetShapeType() == LibUtilities::eTriangle)
846  {
847  // Use edge 0 to define basis of order relevant to edge
848  switch(expansion->m_basisKeyVector[edge_id].GetBasisType())
849  {
851  {
852  switch(expansion->m_basisKeyVector[edge_id].GetPointsType())
853  {
855  {
857  return LibUtilities::BasisKey(expansion->m_basisKeyVector[0].GetBasisType(),nummodes,pkey);
858  }
859  break;
860 
861  default:
862  ASSERTL0(false,"Unexpected points distribution");
863 
864  // It doesn't matter what we return
865  // here since the ASSERT will stop
866  // execution. Just return something
867  // to prevent warnings messages.
869  return LibUtilities::BasisKey(expansion->m_basisKeyVector[0].GetBasisType(),nummodes,pkey);
870  break;
871  }
872  }
873  break;
874  case LibUtilities::eOrtho_B: // Assume this is called from nodal triangular basis
875  {
876  switch(expansion->m_basisKeyVector[edge_id].GetPointsType())
877  {
879  {
882  }
883  break;
884 
885  default:
886  ASSERTL0(false,"Unexpected points distribution");
887 
888  // It doesn't matter what we return
889  // here since the ASSERT will stop
890  // execution. Just return something
891  // to prevent warnings messages.
893  return LibUtilities::BasisKey(expansion->m_basisKeyVector[0].GetBasisType(),nummodes,pkey);
894  break;
895  }
896  }
897  break;
899  {
900  switch(expansion->m_basisKeyVector[edge_id].GetPointsType())
901  {
903  {
905  return LibUtilities::BasisKey(expansion->m_basisKeyVector[0].GetBasisType(),nummodes,pkey);
906  }
907  break;
909  {
911  return LibUtilities::BasisKey(expansion->m_basisKeyVector[0].GetBasisType(),nummodes,pkey);
912  }
913  break;
914 
915  default:
916  ASSERTL0(false,"Unexpected points distribution");
917 
918  // It doesn't matter what we return
919  // here since the ASSERT will stop
920  // execution. Just return something
921  // to prevent warnings messages.
923  return LibUtilities::BasisKey(expansion->m_basisKeyVector[0].GetBasisType(),nummodes,pkey);
924  break;
925  }
926  }
927  break;
929  {
930  switch(expansion->m_basisKeyVector[edge_id].GetPointsType())
931  {
933  {
935  return LibUtilities::BasisKey(expansion->m_basisKeyVector[0].GetBasisType(),nummodes,pkey);
936  }
937  break;
938  default:
939  ASSERTL0(false,"Unexpected points distribution");
940  // It doesn't matter what we return here
941  // since the ASSERT will stop execution.
942  // Just return something to prevent
943  // warnings messages.
945  return LibUtilities::BasisKey(expansion->m_basisKeyVector[0].GetBasisType(),nummodes,pkey);
946  break;
947  }
948  }
949  break;
950 
951  default:
952  ASSERTL0(false,"Unexpected basis distribution");
953  // It doesn't matter what we return here since the
954  // ASSERT will stop execution. Just return
955  // something to prevent warnings messages.
957  return LibUtilities::BasisKey(expansion->m_basisKeyVector[0].GetBasisType(),nummodes,pkey);
958  }
959  }
960  else
961  {
962  // Quadrilateral
963  const LibUtilities::PointsKey pkey(numpoints,expansion->m_basisKeyVector[edge_id].GetPointsType());
964  return LibUtilities::BasisKey(expansion->m_basisKeyVector[edge_id].GetBasisType(),nummodes,pkey);
965  }
966 
967  ASSERTL0(false, "Unable to determine edge points type.");
969  }
970  }; //end of namespace
971 }; //end of namespace
972 
973 //
974 // $Log: MeshGraph2D.cpp,v $
975 // Revision 1.41 2009/12/17 02:08:04 bnelson
976 // Fixed visual studio compiler warning.
977 //
978 // Revision 1.40 2009/10/22 17:41:47 cbiotto
979 // Update for variable order expansion
980 //
981 // Revision 1.39 2009/07/02 13:32:24 sehunchun
982 // *** empty log message ***
983 //
984 // Revision 1.38 2009/07/02 11:39:44 sehunchun
985 // Modification for 2D gemoetry embedded in 3D
986 //
987 // Revision 1.37 2009/05/01 13:23:21 pvos
988 // Fixed various bugs
989 //
990 // Revision 1.36 2009/04/20 16:13:23 sherwin
991 // Modified Import and Write functions and redefined how Expansion is used
992 //
993 // Revision 1.35 2009/01/21 16:59:03 pvos
994 // Added additional geometric factors to improve efficiency
995 //
996 // Revision 1.34 2009/01/12 10:26:59 pvos
997 // Added input tags for nodal expansions
998 //
999 // Revision 1.33 2008/09/12 11:26:19 pvos
1000 // Updates for mappings in 3D
1001 //
1002 // Revision 1.32 2008/09/09 14:21:44 sherwin
1003 // Updates for first working version of curved edges
1004 //
1005 // Revision 1.31 2008/08/14 22:11:03 sherwin
1006 // Mods for HDG update
1007 //
1008 // Revision 1.30 2008/07/29 22:23:36 sherwin
1009 // various mods for DG advection solver in Multiregions. Added virtual calls to Geometry, Geometry1D, 2D and 3D
1010 //
1011 // Revision 1.29 2008/05/29 19:07:39 delisi
1012 // Removed the Write(..) methods, so it is only in the base MeshGraph class. Also, added a line to set the global ID of the geometry object for every element read in.
1013 //
1014 // Revision 1.28 2008/05/28 21:42:18 jfrazier
1015 // Minor comment spelling change.
1016 //
1017 // Revision 1.27 2008/03/18 14:14:49 pvos
1018 // Update for nodal triangular helmholtz solver
1019 //
1020 // Revision 1.26 2008/03/11 17:02:24 jfrazier
1021 // Modified the GetElementsFromEdge to use the domain.
1022 //
1023 // Revision 1.25 2008/01/21 19:58:14 sherwin
1024 // Updated so that QuadGeom and TriGeom have SegGeoms instead of EdgeComponents
1025 //
1026 // Revision 1.24 2007/12/17 20:27:24 sherwin
1027 // Added normals to GeomFactors
1028 //
1029 // Revision 1.23 2007/12/14 17:39:18 jfrazier
1030 // Fixed composite reader to handle ranges and comma separated lists.
1031 //
1032 // Revision 1.22 2007/12/11 21:51:53 jfrazier
1033 // Updated 2d components so elements could be retrieved from edges.
1034 //
1035 // Revision 1.21 2007/12/04 03:02:26 jfrazier
1036 // Changed to stringstream.
1037 //
1038 // Revision 1.20 2007/09/20 22:25:06 jfrazier
1039 // Added expansion information to meshgraph class.
1040 //
1041 // Revision 1.19 2007/07/26 01:38:33 jfrazier
1042 // Cleanup of some attribute reading code.
1043 //
1044 // Revision 1.18 2007/07/24 16:52:09 jfrazier
1045 // Added domain code.
1046 //
1047 // Revision 1.17 2007/07/05 04:21:10 jfrazier
1048 // Changed id format and propagated from 1d to 2d.
1049 //
1050 // Revision 1.16 2007/06/10 02:27:11 jfrazier
1051 // Another checkin with an incremental completion of the boundary conditions reader
1052 //
1053 // Revision 1.15 2007/06/07 23:55:24 jfrazier
1054 // Intermediate revisions to add parsing for boundary conditions file.
1055 //
1056 // Revision 1.14 2007/05/28 21:48:42 sherwin
1057 // Update for 2D functionality
1058 //
1059 // Revision 1.13 2006/10/17 22:26:01 jfrazier
1060 // Added capability to specify ranges in composite definition.
1061 //
1062 // Revision 1.12 2006/10/17 18:42:54 jfrazier
1063 // Removed "NUMBER" attribute in items.
1064 //
1065 // Revision 1.11 2006/09/26 23:41:53 jfrazier
1066 // Updated to account for highest level NEKTAR tag and changed the geometry tag to GEOMETRY.
1067 //
1068 // Revision 1.10 2006/08/24 18:50:00 jfrazier
1069 // Completed error checking on permissable composite item combinations.
1070 //
1071 // Revision 1.9 2006/08/18 19:37:17 jfrazier
1072 // *** empty log message ***
1073 //
1074 // Revision 1.8 2006/08/17 22:55:00 jfrazier
1075 // Continued adding code to process composites in the mesh2d.
1076 //
1077 // Revision 1.7 2006/08/16 23:34:42 jfrazier
1078 // *** empty log message ***
1079 //
1080 // Revision 1.6 2006/06/02 18:48:40 sherwin
1081 // Modifications to make ProjectLoc2D run bit there are bus errors for order > 3
1082 //
1083 // Revision 1.5 2006/06/01 14:15:30 sherwin
1084 // Added typdef of boost wrappers and made GeoFac a boost shared pointer.
1085 //
1086 // Revision 1.4 2006/05/30 14:00:04 sherwin
1087 // Updates to make MultiRegions and its Demos work
1088 //
1089 // Revision 1.3 2006/05/23 19:56:33 jfrazier
1090 // These build and run, but the expansion pieces are commented out
1091 // because they would not run.
1092 //
1093 // Revision 1.2 2006/05/09 13:37:01 jfrazier
1094 // Removed duplicate definition of shared vertex pointer.
1095 //
1096 // Revision 1.1 2006/05/04 18:59:01 kirby
1097 // *** empty log message ***
1098 //
1099 // Revision 1.11 2006/04/11 23:18:11 jfrazier
1100 // Completed MeshGraph2D for tri's and quads. Not thoroughly tested.
1101 //
1102 // Revision 1.10 2006/04/09 02:08:35 jfrazier
1103 // Added precompiled header.
1104 //
1105 // Revision 1.9 2006/04/04 23:12:37 jfrazier
1106 // More updates to readers. Still work to do on MeshGraph2D to store tris and quads.
1107 //
1108 // Revision 1.8 2006/03/25 00:58:29 jfrazier
1109 // Many changes dealing with fundamental structure and reading/writing.
1110 //
1111 // Revision 1.7 2006/03/12 14:20:43 sherwin
1112 //
1113 // First compiling version of SpatialDomains and associated modifications
1114 //
1115 // Revision 1.6 2006/03/12 07:42:03 sherwin
1116 //
1117 // Updated member names and StdRegions call. Still has not been compiled
1118 //
1119 // Revision 1.5 2006/02/26 21:19:43 bnelson
1120 // Fixed a variety of compiler errors caused by updates to the coding standard.
1121 //
1122 // Revision 1.4 2006/02/19 01:37:34 jfrazier
1123 // Initial attempt at bringing into conformance with the coding standard. Still more work to be done. Has not been compiled.
1124 //
1125 //
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:198
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:191
void ReadEdges(TiXmlDocument &doc)
void ReadComposites(TiXmlDocument &doc)
std::map< int, std::string > m_compositesLabels
Definition: MeshGraph.h:431
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
void ReadCurves(TiXmlDocument &doc)
Definition: MeshGraph.cpp:1181
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
boost::shared_ptr< QuadGeom > QuadGeomSharedPtr
Definition: QuadGeom.h:54
void ReadElements(TiXmlDocument &doc)
LibUtilities::BasisKey GetEdgeBasisKey(SegGeomSharedPtr edge, const std::string variable="DefaultVar")
Return the BasisKey corresponding to an edge of an element If the expansion is a triangle the Modifie...
Principle Modified Functions .
Definition: BasisType.h:49
PointGeomSharedPtr GetVertex(int id)
Definition: MeshGraph.h:587
STL namespace.
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:51
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
virtual void ReadGeometry(const std::string &infilename)
Read will read the meshgraph vertices given a filename.
Definition: MeshGraph.cpp:235
static StdRegions::Orientation GetEdgeOrientation(const SegGeom &edge1, const SegGeom &edge2)
Get the orientation of edge1.
Definition: SegGeom.cpp:293
Gauss Radau pinned at x=-1, .
Definition: PointsType.h:59
std::vector< GeometrySharedPtr >::iterator GeometryVectorIter
Definition: Geometry.h:58
Principle Orthogonal Functions .
Definition: BasisType.h:47
boost::shared_ptr< ElementEdge > ElementEdgeSharedPtr
Definition: MeshGraph.h:132
void ReadGeometry(const std::string &infilename)
Read will read the meshgraph vertices given a filename.
Definition: MeshGraph2D.cpp:65
boost::shared_ptr< SegGeom > SegGeomSharedPtr
Definition: Geometry2D.h:60
Principle Modified Functions .
Definition: BasisType.h:50
boost::shared_ptr< DomainRange > DomainRangeShPtr
Definition: MeshGraph.h:157
std::map< int, Composite >::iterator CompositeMapIter
Definition: MeshGraph.h:116
Defines a specification for a set of points.
Definition: Points.h:58
boost::shared_ptr< GeometryVector > Composite
Definition: MeshGraph.h:114
ElementEdgeVectorSharedPtr GetElementsFromEdge(SegGeomSharedPtr edge)
Return the elements (shared ptrs) that have this edge.
static const int kNedges
Get the orientation of face1.
Definition: TriGeom.h:98
boost::shared_ptr< ElementEdgeVector > ElementEdgeVectorSharedPtr
Definition: MeshGraph.h:134
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
std::vector< CompositeMap > m_domain
Definition: MeshGraph.h:432
boost::shared_ptr< Expansion > ExpansionShPtr
Definition: MeshGraph.h:173
Base class for a spectral/hp element mesh.
Definition: MeshGraph.h:186
void ReadDomain(TiXmlDocument &doc)
Definition: MeshGraph.cpp:1087
bool CheckRange(Geometry2D &geom)
Check if goemetry is in range definition if activated.
Definition: MeshGraph.cpp:2029
boost::shared_ptr< Geometry1D > Geometry1DSharedPtr
Definition: Geometry1D.h:48
ExpansionShPtr GetExpansion(GeometrySharedPtr geom, const std::string variable="DefaultVar")
Definition: MeshGraph.cpp:2352
boost::shared_ptr< TriGeom > TriGeomSharedPtr
Definition: TriGeom.h:58
static const BasisKey NullBasisKey(eNoBasisType, 0, NullPointsKey)
Defines a null basis with no type or points.
void ReadExpansions(const std::string &infilename)
Read the expansions given the XML file path.
Definition: MeshGraph.cpp:585
Lagrange for SEM basis .
Definition: BasisType.h:53
void ResolveGeomRef(const std::string &prevToken, const std::string &token, Composite &composite)
Describes the specification for a Basis.
Definition: Basis.h:50
boost::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:60
1D Gauss-Lobatto-Legendre quadrature points
Definition: PointsType.h:52
int ZlibDecodeFromBase64Str(std::string &in64, std::vector< T > &out)
Definition: CompressData.h:243
SegGeomSharedPtr GetSegGeom(int eID)