Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MeshGraph1D.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: MeshGraph1D.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description:
33 //
34 //
35 ////////////////////////////////////////////////////////////////////////////////
36 
39 #include <tinyxml.h>
40 
41 namespace Nektar
42 {
43  namespace SpatialDomains
44  {
45 
47  {
48  }
49 
51  const DomainRangeShPtr &rng)
52  : MeshGraph(pSession,rng)
53  {
54  ReadGeometry (pSession->GetDocument());
55  ReadExpansions(pSession->GetDocument());
56  }
57 
59  {
60  }
61 
62  // \brief Read segments (and general MeshGraph) given filename.
63  void MeshGraph1D::ReadGeometry(const std::string &infilename)
64  {
65  TiXmlDocument doc(infilename);
66 
67  bool loadOkay = doc.LoadFile();
68  std::stringstream errstr;
69  errstr << "Unable to load file: " << infilename << "\n";
70  errstr << doc.ErrorDesc() << " (Line " << doc.ErrorRow()
71  << ", Column " << doc.ErrorCol() << ")";
72  ASSERTL0(loadOkay, errstr.str());
73 
74  ReadGeometry(doc);
75  }
76 
77  // \brief Read segments (and general MeshGraph) given TiXmlDocument.
78  void MeshGraph1D::ReadGeometry(TiXmlDocument &doc)
79  {
80  // Read mesh first
82  TiXmlHandle docHandle(&doc);
83 
84  TiXmlElement* mesh = NULL;
85 
86  /// Look for all geometry related data in GEOMETRY block.
87  mesh = docHandle.FirstChildElement("NEKTAR").FirstChildElement("GEOMETRY").Element();
88 
89  ASSERTL0(mesh, "Unable to find GEOMETRY tag in file.");
90 
91  ReadElements(doc);
92  ReadComposites(doc);
93  ReadDomain(doc);
94  }
95 
96  void MeshGraph1D::ReadElements(TiXmlDocument &doc)
97  {
98  /// We know we have it since we made it this far.
99  TiXmlHandle docHandle(&doc);
100  TiXmlElement* mesh = docHandle.FirstChildElement("NEKTAR").FirstChildElement("GEOMETRY").Element();
101  TiXmlElement* field = NULL;
102 
103  /// Look for elements in ELEMENT block.
104  field = mesh->FirstChildElement("ELEMENT");
105 
106  ASSERTL0(field, "Unable to find ELEMENT tag in file.");
107 
108  int nextElementNumber = -1;
109 
110  /// All elements are of the form: "<S ID = n> ... </S>", with
111  /// ? being the element type.
112 
113  TiXmlElement *segment = field->FirstChildElement("S");
114 
115  while (segment)
116  {
117  nextElementNumber++;
118 
119  int indx;
120  int err = segment->QueryIntAttribute("ID", &indx);
121  ASSERTL0(err == TIXML_SUCCESS, "Unable to read element attribute ID.");
122 // ASSERTL0(indx == nextElementNumber, "Element IDs must begin with zero and be sequential.");
123 
124  TiXmlNode* elementChild = segment->FirstChild();
125  while(elementChild && elementChild->Type() != TiXmlNode::TEXT)
126  {
127  elementChild = elementChild->NextSibling();
128  }
129 
130  ASSERTL0(elementChild, "Unable to read element description body.");
131  std::string elementStr = elementChild->ToText()->ValueStr();
132 
133  /// Parse out the element components corresponding to type of element.
134  /// Read two vertex numbers
135  int vertex1, vertex2;
136  std::istringstream elementDataStrm(elementStr.c_str());
137 
138  try
139  {
140  elementDataStrm >> vertex1;
141  elementDataStrm >> vertex2;
142 
143  ASSERTL0(!elementDataStrm.fail(), (std::string("Unable to read element data for SEGMENT: ") + elementStr).c_str());
144 
145  PointGeomSharedPtr v1 = GetVertex(vertex1);
146  PointGeomSharedPtr v2 = GetVertex(vertex2);
148  seg->SetGlobalID(indx);
149  m_segGeoms[indx] = seg;
150  }
151  catch(...)
152  {
154  (std::string("Unable to read element data for segment: ") + elementStr).c_str());
155  }
156 
157  /// Keep looking for additional segments
158  segment = segment->NextSiblingElement("S");
159  }
160 
161  ASSERTL0(nextElementNumber >= 0, "At least one element must be specified.");
162  }
163 
164  void MeshGraph1D::ReadComposites(TiXmlDocument &doc)
165  {
166  TiXmlHandle docHandle(&doc);
167 
168  /// We know we have it since we made it this far.
169  TiXmlElement* mesh = docHandle.FirstChildElement("NEKTAR").FirstChildElement("GEOMETRY").Element();
170  TiXmlElement* field = NULL;
171 
172  ASSERTL0(mesh, "Unable to find GEOMETRY tag in file.");
173 
174  /// Look for elements in ELEMENT block.
175  field = mesh->FirstChildElement("COMPOSITE");
176 
177  ASSERTL0(field, "Unable to find COMPOSITE tag in file.");
178 
179  TiXmlElement *node = field->FirstChildElement("C");
180 
181  // Sequential counter for the composite numbers.
182  int nextCompositeNumber = -1;
183 
184  while (node)
185  {
186  /// All elements are of the form: "<? ID="#"> ... </?>", with
187  /// ? being the element type.
188 
189  nextCompositeNumber++;
190 
191  int indx;
192  int err = node->QueryIntAttribute("ID", &indx);
193  ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
194  //ASSERTL0(indx == nextCompositeNumber, "Composite IDs must begin with zero and be sequential.");
195 
196  TiXmlNode* compositeChild = node->FirstChild();
197  // This is primarily to skip comments that may be present.
198  // Comments appear as nodes just like elements.
199  // We are specifically looking for text in the body
200  // of the definition.
201  while(compositeChild && compositeChild->Type() != TiXmlNode::TEXT)
202  {
203  compositeChild = compositeChild->NextSibling();
204  }
205 
206  ASSERTL0(compositeChild, "Unable to read composite definition body.");
207  std::string compositeStr = compositeChild->ToText()->ValueStr();
208 
209  /// Parse out the element components corresponding to type of element.
210 
211  std::istringstream compositeDataStrm(compositeStr.c_str());
212 
213  try
214  {
215  bool first = true;
216  std::string prevCompositeElementStr;
217 
218  while (!compositeDataStrm.fail())
219  {
220  std::string compositeElementStr;
221  compositeDataStrm >> compositeElementStr;
222 
223  if (!compositeDataStrm.fail())
224  {
225  if (first)
226  {
227  first = false;
228 
229  Composite curVector = MemoryManager<std::vector<GeometrySharedPtr> >::AllocateSharedPtr();
230  m_meshComposites[indx] = curVector;
231  }
232 
233  if (compositeElementStr.length() > 0)
234  {
235  ResolveGeomRef(prevCompositeElementStr, compositeElementStr, m_meshComposites[indx]);
236  }
237  prevCompositeElementStr = compositeElementStr;
238  }
239  }
240  }
241  catch(...)
242  {
244  (std::string("Unable to read COMPOSITE data for composite: ") + compositeStr).c_str());
245  }
246 
247  /// Keep looking for additional composite definitions.
248  node = node->NextSiblingElement("C");
249  }
250 
251  ASSERTL0(nextCompositeNumber >= 0, "At least one composite must be specified.");
252  }
253 
254 
255  // Take the string that is the composite reference and find the
256  // pointer to the Geometry object corresponding to it.
257 
258  // Only allow segments to be grouped for 1D mesh.
259  void MeshGraph1D::ResolveGeomRef(const std::string &prevToken, const std::string &token,
260  Composite& composite)
261  {
262  try
263  {
264  std::istringstream tokenStream(token);
265  std::istringstream prevTokenStream(prevToken);
266 
267  char type;
268  char prevType;
269 
270  tokenStream >> type;
271 
272  std::string::size_type indxBeg = token.find_first_of('[') + 1;
273  std::string::size_type indxEnd = token.find_last_of(']') - 1;
274 
275  ASSERTL0(indxBeg <= indxEnd, (std::string("Error reading index definition:") + token).c_str());
276 
277  std::string indxStr = token.substr(indxBeg, indxEnd - indxBeg + 1);
278 
279  typedef vector<unsigned int> SeqVectorType;
280  SeqVectorType seqVector;
281 
282  if (!ParseUtils::GenerateSeqVector(indxStr.c_str(), seqVector))
283  {
284  NEKERROR(ErrorUtil::efatal, (std::string("Ill-formed sequence definition: ") + indxStr).c_str());
285  }
286 
287  prevTokenStream >> prevType;
288 
289  // All composites must be of the same dimension.
290  bool validSequence = (prevToken.empty() || // No previous, then current is just fine.
291  (type == 'V' && prevType == 'V') ||
292  (type == 'S' && prevType == 'S'));
293 
294  ASSERTL0(validSequence, (std::string("Invalid combination of composite items: ")
295  + type + " and " + prevType + ".").c_str());
296 
297  switch(type)
298  {
299  case 'V': // Vertex
300  for (SeqVectorType::iterator iter=seqVector.begin(); iter!=seqVector.end(); ++iter)
301  {
302  if (m_vertSet.find(*iter) == m_vertSet.end())
303  {
304  char errStr[16] = "";
305  ::sprintf(errStr, "%d", *iter);
306  NEKERROR(ErrorUtil::ewarning, (std::string("Unknown vertex index: ") + errStr).c_str());
307  }
308  else
309  {
310  composite->push_back(m_vertSet[*iter]);
311  }
312  }
313  break;
314 
315  case 'S': // Segment
316  for (SeqVectorType::iterator iter=seqVector.begin(); iter!=seqVector.end(); ++iter)
317  {
318  if (m_segGeoms.find(*iter) == m_segGeoms.end())
319  {
320  char errStr[16] = "";
321  ::sprintf(errStr, "%d", *iter);
322  NEKERROR(ErrorUtil::ewarning, (std::string("Unknown segment index: ") + errStr).c_str());
323  }
324  else
325  {
326  composite->push_back(m_segGeoms[*iter]);
327  }
328  }
329  break;
330 
331  default:
332  NEKERROR(ErrorUtil::efatal, (std::string("Unrecognized composite token: ") + token).c_str());
333  }
334  }
335  catch(...)
336  {
337  NEKERROR(ErrorUtil::efatal, (std::string("Problem processing composite token: ") + token).c_str());
338  }
339 
340  return;
341  }
342 
343  }; //end of namespace
344 }; //end of namespace
345 
346 //
347 // $Log: MeshGraph1D.cpp,v $
348 // Revision 1.17 2007/12/04 03:01:18 jfrazier
349 // Changed to stringstream.
350 //
351 // Revision 1.16 2007/09/20 22:25:06 jfrazier
352 // Added expansion information to meshgraph class.
353 //
354 // Revision 1.15 2007/07/28 05:44:27 sherwin
355 // Fixed for new MemoryManager call
356 //
357 // Revision 1.14 2007/07/26 01:38:32 jfrazier
358 // Cleanup of some attribute reading code.
359 //
360 // Revision 1.13 2007/07/24 16:52:09 jfrazier
361 // Added domain code.
362 //
363 // Revision 1.12 2007/07/23 16:54:30 jfrazier
364 // Change a dynamic allocation using new to memory manager allocate.
365 //
366 // Revision 1.11 2007/07/05 04:21:10 jfrazier
367 // Changed id format and propagated from 1d to 2d.
368 //
369 // Revision 1.10 2007/06/10 02:27:10 jfrazier
370 // Another checkin with an incremental completion of the boundary conditions reader.
371 //
372 // Revision 1.9 2007/06/07 23:55:24 jfrazier
373 // Intermediate revisions to add parsing for boundary conditions file.
374 //
375 // Revision 1.8 2007/03/14 21:24:08 sherwin
376 // Update for working version of MultiRegions up to ExpList1D
377 //
378 // Revision 1.7 2006/10/15 06:18:58 sherwin
379 // Moved NekPoint out of namespace LibUtilities
380 //
381 // Revision 1.6 2006/09/26 23:41:53 jfrazier
382 // Updated to account for highest level NEKTAR tag and changed the geometry tag to GEOMETRY.
383 //
384 // Revision 1.5 2006/06/01 14:15:30 sherwin
385 // Added typdef of boost wrappers and made GeoFac a boost shared pointer.
386 //
387 // Revision 1.4 2006/05/23 19:56:33 jfrazier
388 // These build and run, but the expansion pieces are commented out
389 // because they would not run.
390 //
391 // Revision 1.3 2006/05/16 22:28:31 sherwin
392 // Updates to add in FaceComponent call to constructors
393 //
394 // Revision 1.2 2006/05/16 20:12:59 jfrazier
395 // Minor fixes to correct bugs.
396 //
397 // Revision 1.1 2006/05/04 18:59:01 kirby
398 // *** empty log message ***
399 //
400 // Revision 1.17 2006/04/09 02:08:35 jfrazier
401 // Added precompiled header.
402 //
403 // Revision 1.16 2006/04/04 23:12:37 jfrazier
404 // More updates to readers. Still work to do on MeshGraph2D to store tris and quads.
405 //
406 // Revision 1.15 2006/03/25 00:58:29 jfrazier
407 // Many changes dealing with fundamental structure and reading/writing.
408 //
409 // Revision 1.14 2006/03/12 14:20:43 sherwin
410 //
411 // First compiling version of SpatialDomains and associated modifications
412 //
413 // Revision 1.13 2006/03/12 07:42:03 sherwin
414 //
415 // Updated member names and StdRegions call. Still has not been compiled
416 //
417 // Revision 1.12 2006/02/26 21:19:43 bnelson
418 // Fixed a variety of compiler errors caused by updates to the coding standard.
419 //
420 // Revision 1.11 2006/02/19 01:37:33 jfrazier
421 // Initial attempt at bringing into conformance with the coding standard. Still more work to be done. Has not been compiled.
422 //
423 //