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