Nektar++
Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | List of all members
Nektar::SpatialDomains::MeshGraphXml Class Reference

#include <MeshGraphXml.h>

Inheritance diagram for Nektar::SpatialDomains::MeshGraphXml:
[legend]

Public Member Functions

 MeshGraphXml ()
 
virtual ~MeshGraphXml ()
 
virtual void WriteGeometry (std::string &outfilename, bool defaultExp=false, const LibUtilities::FieldMetaDataMap &metadata=LibUtilities::NullFieldMetaDataMap)
 Write out an XML file containing the GEOMETRY block representing this MeshGraph instance inside a NEKTAR tag. More...
 
void WriteXMLGeometry (std::string outname, std::vector< std::set< unsigned int >> elements, std::vector< unsigned int > partitions)
 
virtual void ReadGeometry (DomainRangeShPtr rng, bool fillGraph)
 
virtual void PartitionMesh (LibUtilities::SessionReaderSharedPtr session)
 
- Public Member Functions inherited from Nektar::SpatialDomains::MeshGraph
 MeshGraph ()
 
virtual ~MeshGraph ()
 
void Empty (int dim, int space)
 
void FillGraph ()
 
void FillBoundingBoxTree ()
 
std::vector< int > GetElementsContainingPoint (PointGeomSharedPtr p)
 
void ReadExpansions ()
 
int GetMeshDimension ()
 Dimension of the mesh (can be a 1D curve in 3D space). More...
 
int GetSpaceDimension ()
 Dimension of the space (can be a 1D curve in 3D space). More...
 
void SetDomainRange (NekDouble xmin, NekDouble xmax, NekDouble ymin=NekConstants::kNekUnsetDouble, NekDouble ymax=NekConstants::kNekUnsetDouble, NekDouble zmin=NekConstants::kNekUnsetDouble, NekDouble zmax=NekConstants::kNekUnsetDouble)
 
bool CheckRange (Geometry2D &geom)
 Check if goemetry is in range definition if activated. More...
 
bool CheckRange (Geometry3D &geom)
 Check if goemetry is in range definition if activated. More...
 
CompositeSharedPtr GetComposite (int whichComposite)
 
GeometrySharedPtr GetCompositeItem (int whichComposite, int whichItem)
 
void GetCompositeList (const std::string &compositeStr, CompositeMap &compositeVector) const
 
std::map< int, CompositeSharedPtr > & GetComposites ()
 
std::map< int, std::string > & GetCompositesLabels ()
 
std::vector< std::map< int, CompositeSharedPtr > > & GetDomain ()
 
std::map< int, CompositeSharedPtr > & GetDomain (int domain)
 
const ExpansionMapGetExpansions (const std::string variable="DefaultVar")
 
ExpansionShPtr GetExpansion (GeometrySharedPtr geom, const std::string variable="DefaultVar")
 
void SetExpansions (std::vector< LibUtilities::FieldDefinitionsSharedPtr > &fielddef)
 Sets expansions given field definitions. More...
 
void SetExpansions (std::vector< LibUtilities::FieldDefinitionsSharedPtr > &fielddef, std::vector< std::vector< LibUtilities::PointsType >> &pointstype)
 Sets expansions given field definition, quadrature points. More...
 
void SetExpansionsToEvenlySpacedPoints (int npoints=0)
 Sets expansions to have equispaced points. More...
 
void SetExpansionsToPolyOrder (int nmodes)
 Reset expansion to have specified polynomial order nmodes. More...
 
void SetExpansionsToPointOrder (int npts)
 Reset expansion to have specified point order npts. More...
 
void SetExpansions (const std::string variable, ExpansionMapShPtr &exp)
 This function sets the expansion #exp in map with entry #variable. More...
 
void SetSession (LibUtilities::SessionReaderSharedPtr pSession)
 
void SetBasisKey (LibUtilities::ShapeType shape, LibUtilities::BasisKeyVector &keys, std::string var="DefaultVar")
 Sets the basis key for all expansions of the given shape. More...
 
bool SameExpansions (const std::string var1, const std::string var2)
 
bool CheckForGeomInfo (std::string parameter)
 
const std::string GetGeomInfo (std::string parameter)
 
LibUtilities::BasisKeyVector DefineBasisKeyFromExpansionTypeHomo (GeometrySharedPtr in, ExpansionType type_x, ExpansionType type_y, ExpansionType type_z, const int nummodes_x, const int nummodes_y, const int nummodes_z)
 
int GetNvertices ()
 
PointGeomSharedPtr GetVertex (int id)
 
SegGeomSharedPtr GetSegGeom (int id)
 
CurveMapGetCurvedEdges ()
 
CurveMapGetCurvedFaces ()
 
std::map< int, PointGeomSharedPtr > & GetAllPointGeoms ()
 
std::map< int, SegGeomSharedPtr > & GetAllSegGeoms ()
 
TriGeomMapGetAllTriGeoms ()
 
QuadGeomMapGetAllQuadGeoms ()
 
TetGeomMapGetAllTetGeoms ()
 
PyrGeomMapGetAllPyrGeoms ()
 
PrismGeomMapGetAllPrismGeoms ()
 
HexGeomMapGetAllHexGeoms ()
 
int GetNumElements ()
 
Geometry2DSharedPtr GetGeometry2D (int gID)
 
LibUtilities::BasisKey GetEdgeBasisKey (SegGeomSharedPtr edge, const std::string variable="DefaultVar")
 
GeometryLinkSharedPtr GetElementsFromEdge (Geometry1DSharedPtr edge)
 
GeometryLinkSharedPtr GetElementsFromFace (Geometry2DSharedPtr face)
 
LibUtilities::BasisKey GetFaceBasisKey (Geometry2DSharedPtr face, const int facedir, const std::string variable="DefaultVar")
 3D functions More...
 
CompositeOrderingGetCompositeOrdering ()
 
BndRegionOrderingGetBndRegionOrdering ()
 
std::map< int, MeshEntityCreateMeshEntities ()
 Create mesh entities for this graph. More...
 
CompositeDescriptor CreateCompositeDescriptor ()
 

Static Public Member Functions

static MeshGraphSharedPtr create ()
 
- Static Public Member Functions inherited from Nektar::SpatialDomains::MeshGraph
static MeshGraphSharedPtr Read (const LibUtilities::SessionReaderSharedPtr pSession, DomainRangeShPtr rng=NullDomainRangeShPtr, bool fillGraph=true)
 
static LibUtilities::BasisKeyVector DefineBasisKeyFromExpansionType (GeometrySharedPtr in, ExpansionType type, const int order)
 

Static Public Attributes

static std::string className
 

Protected Member Functions

virtual void ReadVertices ()
 
virtual void ReadCurves ()
 
void ReadDomain ()
 
virtual void ReadEdges ()
 
virtual void ReadFaces ()
 
void ReadElements ()
 
void ReadComposites ()
 
virtual void ReadElements1D ()
 
virtual void ReadElements2D ()
 
virtual void ReadElements3D ()
 
void ResolveGeomRef (const std::string &prevToken, const std::string &token, CompositeSharedPtr &composite)
 
void ResolveGeomRef1D (const std::string &prevToken, const std::string &token, CompositeSharedPtr &composite)
 
void ResolveGeomRef2D (const std::string &prevToken, const std::string &token, CompositeSharedPtr &composite)
 
void ResolveGeomRef3D (const std::string &prevToken, const std::string &token, CompositeSharedPtr &composite)
 
virtual void WriteVertices (TiXmlElement *geomTag, PointGeomMap &verts)
 
virtual void WriteEdges (TiXmlElement *geomTag, SegGeomMap &edges)
 
virtual void WriteTris (TiXmlElement *faceTag, TriGeomMap &tris)
 
virtual void WriteQuads (TiXmlElement *faceTag, QuadGeomMap &quads)
 
virtual void WriteHexs (TiXmlElement *elmtTag, HexGeomMap &hexs)
 
virtual void WritePrisms (TiXmlElement *elmtTag, PrismGeomMap &pris)
 
virtual void WritePyrs (TiXmlElement *elmtTag, PyrGeomMap &pyrs)
 
virtual void WriteTets (TiXmlElement *elmtTag, TetGeomMap &tets)
 
virtual void WriteCurves (TiXmlElement *geomTag, CurveMap &edges, CurveMap &faces)
 
void WriteComposites (TiXmlElement *geomTag, CompositeMap &comps)
 
void WriteDomain (TiXmlElement *geomTag, std::vector< CompositeMap > &domain)
 
void WriteDefaultExpansion (TiXmlElement *root)
 
CompositeOrdering CreateCompositeOrdering ()
 
- Protected Member Functions inherited from Nektar::SpatialDomains::MeshGraph
void PopulateFaceToElMap (Geometry3DSharedPtr element, int kNfaces)
 Given a 3D geometry object #element, populate the face to element map m_faceToElMap which maps faces to their corresponding element(s). More...
 
ExpansionMapShPtr SetUpExpansionMap ()
 
std::string GetCompositeString (CompositeSharedPtr comp)
 Returns a string representation of a composite. More...
 

Additional Inherited Members

- Protected Attributes inherited from Nektar::SpatialDomains::MeshGraph
LibUtilities::SessionReaderSharedPtr m_session
 
PointGeomMap m_vertSet
 
CurveMap m_curvedEdges
 
CurveMap m_curvedFaces
 
SegGeomMap m_segGeoms
 
TriGeomMap m_triGeoms
 
QuadGeomMap m_quadGeoms
 
TetGeomMap m_tetGeoms
 
PyrGeomMap m_pyrGeoms
 
PrismGeomMap m_prismGeoms
 
HexGeomMap m_hexGeoms
 
int m_meshDimension
 
int m_spaceDimension
 
int m_partition
 
bool m_meshPartitioned
 
CompositeMap m_meshComposites
 
std::map< int, std::string > m_compositesLabels
 
std::vector< CompositeMapm_domain
 
DomainRangeShPtr m_domainRange
 
ExpansionMapShPtrMap m_expansionMapShPtrMap
 
GeomInfoMap m_geomInfo
 
std::unordered_map< int, GeometryLinkSharedPtrm_faceToElMap
 
TiXmlElement * m_xmlGeom
 
CompositeOrdering m_compOrder
 
BndRegionOrdering m_bndRegOrder
 
std::unique_ptr< GeomRTreem_boundingBoxTree
 

Detailed Description

Definition at line 47 of file MeshGraphXml.h.

Constructor & Destructor Documentation

◆ MeshGraphXml()

Nektar::SpatialDomains::MeshGraphXml::MeshGraphXml ( )
inline

Definition at line 50 of file MeshGraphXml.h.

51  {
52  }

◆ ~MeshGraphXml()

virtual Nektar::SpatialDomains::MeshGraphXml::~MeshGraphXml ( )
inlinevirtual

Member Function Documentation

◆ create()

static MeshGraphSharedPtr Nektar::SpatialDomains::MeshGraphXml::create ( )
inlinestatic

Definition at line 69 of file MeshGraphXml.h.

References Nektar::MemoryManager< DataType >::AllocateSharedPtr().

70  {
72  }
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.

◆ CreateCompositeOrdering()

CompositeOrdering Nektar::SpatialDomains::MeshGraphXml::CreateCompositeOrdering ( )
protected

Definition at line 3234 of file MeshGraphXml.cpp.

3235 {
3236  CompositeOrdering ret;
3237 
3238  for (auto &c : m_meshComposites)
3239  {
3240  std::vector<unsigned int> ids;
3241  for (auto &elmt : c.second->m_geomVec)
3242  {
3243  ids.push_back(elmt->GetGlobalID());
3244  }
3245  ret[c.first] = ids;
3246  }
3247 
3248  return ret;
3249 }
std::map< int, std::vector< unsigned int > > CompositeOrdering
Definition: MeshGraph.h:108

◆ PartitionMesh()

void Nektar::SpatialDomains::MeshGraphXml::PartitionMesh ( LibUtilities::SessionReaderSharedPtr  session)
virtual

Implements Nektar::SpatialDomains::MeshGraph.

Definition at line 61 of file MeshGraphXml.cpp.

References ASSERTL0, Nektar::LibUtilities::NekFactory< tKey, tBase, tParam >::CreateInstance(), CellMLToNektar.pycml::format, Nektar::SpatialDomains::GetMeshPartitionFactory(), Nektar::SpatialDomains::NullDomainRangeShPtr, and Nektar::LibUtilities::PortablePath().

63 {
64  // Get row of comm, or the whole comm if not split
65  LibUtilities::CommSharedPtr comm = session->GetComm();
66  LibUtilities::CommSharedPtr commMesh = comm->GetRowComm();
67  const bool isRoot = comm->TreatAsRankZero();
68 
69  m_session = session;
70 
71  // Load file for root process only (since this is always needed)
72  // and determine if the provided geometry has already been
73  // partitioned. This will be the case if the user provides the
74  // directory of mesh partitions as an input. Partitioned geometries
75  // have the attribute
76  // PARTITION=X
77  // where X is the number of the partition (and should match the
78  // process rank). The result is shared with all other processes.
79  int isPartitioned = 0;
80  if (isRoot)
81  {
82  if (m_session->DefinesElement("Nektar/Geometry"))
83  {
84  if (m_session->GetElement("Nektar/Geometry")->Attribute("PARTITION"))
85  {
86  std::cout << "Using pre-partitioned mesh." << std::endl;
87  isPartitioned = 1;
88  }
89  }
90  }
91  comm->Bcast(isPartitioned, 0);
92 
93  // If the mesh is already partitioned, we are done. Remaining
94  // processes must load their partitions.
95  if (isPartitioned)
96  {
97  if (!isRoot)
98  {
99  m_session->InitSession();
100  }
101  }
102  else
103  {
104  // Default partitioner to use is Metis. Use Scotch as default if it is
105  // installed. Override default with command-line flags if they are set.
106  string partitionerName = "Metis";
107  if (GetMeshPartitionFactory().ModuleExists("Scotch"))
108  {
109  partitionerName = "Scotch";
110  }
111  if (session->DefinesCmdLineArgument("use-metis"))
112  {
113  partitionerName = "Metis";
114  }
115  if (session->DefinesCmdLineArgument("use-scotch"))
116  {
117  partitionerName = "Scotch";
118  }
119 
120  // Mesh has not been partitioned so do partitioning if required. Note
121  // in the serial case nothing is done as we have already loaded the
122  // mesh.
123  if (session->DefinesCmdLineArgument("part-only")||
124  session->DefinesCmdLineArgument("part-only-overlapping"))
125  {
126  // Perform partitioning of the mesh only. For this we insist the
127  // code is run in serial (parallel execution is pointless).
128  ASSERTL0(comm->GetSize() == 1,
129  "The 'part-only' option should be used in serial.");
130 
131  // Read 'lite' geometry information
133 
134  // Number of partitions is specified by the parameter.
135  int nParts;
136  auto comp = CreateCompositeDescriptor();
137 
138  MeshPartitionSharedPtr partitioner =
140  partitionerName, session, m_meshDimension,
141  CreateMeshEntities(), comp);
142 
143  if (session->DefinesCmdLineArgument("part-only"))
144  {
145  nParts = session->GetCmdLineArgument<int>("part-only");
146  partitioner->PartitionMesh(nParts, true);
147  }
148  else
149  {
150  nParts = session->GetCmdLineArgument<int>("part-only-overlapping");
151  partitioner->PartitionMesh(nParts, true, true);
152  }
153 
154  vector<set<unsigned int>> elmtIDs;
155  vector<unsigned int> parts(nParts);
156  for (int i = 0; i < nParts; ++i)
157  {
158  vector<unsigned int> elIDs;
159  set<unsigned int> tmp;
160  partitioner->GetElementIDs(i, elIDs);
161  tmp.insert(elIDs.begin(), elIDs.end());
162  elmtIDs.push_back(tmp);
163  parts[i] = i;
164  }
165 
166  this->WriteXMLGeometry(m_session->GetSessionName(), elmtIDs, parts);
167 
168  if (isRoot && session->DefinesCmdLineArgument("part-info"))
169  {
170  partitioner->PrintPartInfo(std::cout);
171  }
172 
173  session->Finalise();
174  exit(0);
175  }
176 
177  if (commMesh->GetSize() > 1)
178  {
179  int nParts = commMesh->GetSize();
180 
181  if (session->GetSharedFilesystem())
182  {
183  vector<unsigned int> keys, vals;
184  int i;
185 
186  if (isRoot)
187  {
188  // Read 'lite' geometry information
190 
191  // Store composite ordering and boundary information.
193  auto comp = CreateCompositeDescriptor();
194 
195  // Create mesh partitioner.
196  MeshPartitionSharedPtr partitioner =
198  partitionerName, session, m_meshDimension,
199  CreateMeshEntities(), comp);
200 
201  partitioner->PartitionMesh(nParts, true);
202 
203  vector<set<unsigned int>> elmtIDs;
204  vector<unsigned int> parts(nParts);
205  for (i = 0; i < nParts; ++i)
206  {
207  vector<unsigned int> elIDs;
208  set<unsigned int> tmp;
209  partitioner->GetElementIDs(i, elIDs);
210  tmp.insert(elIDs.begin(), elIDs.end());
211  elmtIDs.push_back(tmp);
212  parts[i] = i;
213  }
214 
215  // Call WriteGeometry to write out partition files. This
216  // will populate m_bndRegOrder.
217  this->WriteXMLGeometry(
218  m_session->GetSessionName(), elmtIDs, parts);
219 
220  // Communicate orderings to the other processors.
221 
222  // First send sizes of the orderings and boundary
223  // regions to allocate storage on the remote end.
224  keys.resize(2);
225  keys[0] = m_compOrder.size();
226  keys[1] = m_bndRegOrder.size();
227  comm->Bcast(keys, 0);
228 
229  // Construct the keys and sizes of values for composite
230  // ordering
231  keys.resize(m_compOrder.size());
232  vals.resize(m_compOrder.size());
233 
234  i = 0;
235  for (auto &cIt : m_compOrder)
236  {
237  keys[i ] = cIt.first;
238  vals[i++] = cIt.second.size();
239  }
240 
241  // Send across data.
242  comm->Bcast(keys, 0);
243  comm->Bcast(vals, 0);
244  for (auto &cIt : m_compOrder)
245  {
246  comm->Bcast(cIt.second, 0);
247  }
248 
249  // Construct the keys and sizes of values for composite
250  // ordering
251  keys.resize(m_bndRegOrder.size());
252  vals.resize(m_bndRegOrder.size());
253 
254  i = 0;
255  for (auto &bIt : m_bndRegOrder)
256  {
257  keys[i ] = bIt.first;
258  vals[i++] = bIt.second.size();
259  }
260 
261  // Send across data.
262  comm->Bcast(keys, 0);
263  comm->Bcast(vals, 0);
264  for (auto &bIt : m_bndRegOrder)
265  {
266  comm->Bcast(bIt.second, 0);
267  }
268 
269  if (session->DefinesCmdLineArgument("part-info"))
270  {
271  partitioner->PrintPartInfo(std::cout);
272  }
273  }
274  else
275  {
276  keys.resize(2);
277  comm->Bcast(keys, 0);
278 
279  int cmpSize = keys[0];
280  int bndSize = keys[1];
281 
282  keys.resize(cmpSize);
283  vals.resize(cmpSize);
284  comm->Bcast(keys, 0);
285  comm->Bcast(vals, 0);
286 
287  for (int i = 0; i < keys.size(); ++i)
288  {
289  vector<unsigned int> tmp(vals[i]);
290  comm->Bcast(tmp, 0);
291  m_compOrder[keys[i]] = tmp;
292  }
293 
294  keys.resize(bndSize);
295  vals.resize(bndSize);
296  comm->Bcast(keys, 0);
297  comm->Bcast(vals, 0);
298 
299  for (int i = 0; i < keys.size(); ++i)
300  {
301  vector<unsigned int> tmp(vals[i]);
302  comm->Bcast(tmp, 0);
303  m_bndRegOrder[keys[i]] = tmp;
304  }
305  }
306  }
307  else
308  {
309  m_session->InitSession();
311 
312  m_compOrder = CreateCompositeOrdering();
313  auto comp = CreateCompositeDescriptor();
314 
315  // Partitioner now operates in parallel. Each process receives
316  // partitioning over interconnect and writes its own session
317  // file to the working directory.
318  MeshPartitionSharedPtr partitioner =
320  partitionerName, session, m_meshDimension,
321  CreateMeshEntities(), comp);
322 
323  partitioner->PartitionMesh(nParts, false);
324 
325  vector<unsigned int> parts(1), tmp;
326  parts[0] = commMesh->GetRank();
327  vector<set<unsigned int>> elIDs(1);
328  partitioner->GetElementIDs(parts[0], tmp);
329  elIDs[0].insert(tmp.begin(), tmp.end());
330  this->WriteXMLGeometry(session->GetSessionName(), elIDs, parts);
331 
332  if (m_session->DefinesCmdLineArgument("part-info") && isRoot)
333  {
334  partitioner->PrintPartInfo(std::cout);
335  }
336  }
337 
338  // Wait for all processors to finish their writing activities.
339  comm->Block();
340 
341  std::string dirname = m_session->GetSessionName() + "_xml";
342  fs::path pdirname(dirname);
343  boost::format pad("P%1$07d.xml");
344  pad % comm->GetRowComm()->GetRank();
345  fs::path pFilename(pad.str());
346  fs::path fullpath = pdirname / pFilename;
347 
348  std::vector<std::string> filenames = {
349  LibUtilities::PortablePath(fullpath) };
350  m_session->InitSession(filenames);
351  }
352  else if (!isRoot)
353  {
354  // No partitioning, non-root processors need to read the session
355  // file -- handles case where --npz is the same as number of
356  // processors.
357  m_session->InitSession();
358  }
359  }
360 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
LibUtilities::SessionReaderSharedPtr m_session
Definition: MeshGraph.h:435
CompositeDescriptor CreateCompositeDescriptor()
Definition: MeshGraph.cpp:3633
std::shared_ptr< MeshPartition > MeshPartitionSharedPtr
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
CompositeOrdering CreateCompositeOrdering()
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey.
Definition: NekFactory.hpp:144
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41
BndRegionOrdering m_bndRegOrder
Definition: MeshGraph.h:469
void WriteXMLGeometry(std::string outname, std::vector< std::set< unsigned int >> elements, std::vector< unsigned int > partitions)
static DomainRangeShPtr NullDomainRangeShPtr
Definition: MeshGraph.h:129
std::map< int, MeshEntity > CreateMeshEntities()
Create mesh entities for this graph.
Definition: MeshGraph.cpp:3533
CompositeOrdering m_compOrder
Definition: MeshGraph.h:468
MeshPartitionFactory & GetMeshPartitionFactory()
virtual void ReadGeometry(DomainRangeShPtr rng, bool fillGraph)

◆ ReadComposites()

void Nektar::SpatialDomains::MeshGraphXml::ReadComposites ( )
protected

Look for elements in ELEMENT block.

All elements are of the form: "<? ID="#"> ... </?>", with ? being the element type.

Parse out the element components corresponding to type of element.

Keep looking for additional composite definitions.

Definition at line 1845 of file MeshGraphXml.cpp.

References ASSERTL0, and NEKERROR.

1846 {
1847  TiXmlElement *field = NULL;
1848 
1849  /// Look for elements in ELEMENT block.
1850  field = m_xmlGeom->FirstChildElement("COMPOSITE");
1851 
1852  ASSERTL0(field, "Unable to find COMPOSITE tag in file.");
1853 
1854  TiXmlElement *node = field->FirstChildElement("C");
1855 
1856  // Sequential counter for the composite numbers.
1857  int nextCompositeNumber = -1;
1858 
1859  while (node)
1860  {
1861  /// All elements are of the form: "<? ID="#"> ... </?>", with
1862  /// ? being the element type.
1863 
1864  nextCompositeNumber++;
1865 
1866  int indx;
1867  int err = node->QueryIntAttribute("ID", &indx);
1868  ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
1869  // ASSERTL0(indx == nextCompositeNumber, "Composite IDs must begin with
1870  // zero and be sequential.");
1871 
1872  TiXmlNode *compositeChild = node->FirstChild();
1873  // This is primarily to skip comments that may be present.
1874  // Comments appear as nodes just like elements.
1875  // We are specifically looking for text in the body
1876  // of the definition.
1877  while (compositeChild &&
1878  compositeChild->Type() != TiXmlNode::TINYXML_TEXT)
1879  {
1880  compositeChild = compositeChild->NextSibling();
1881  }
1882 
1883  ASSERTL0(compositeChild, "Unable to read composite definition body.");
1884  std::string compositeStr = compositeChild->ToText()->ValueStr();
1885 
1886  /// Parse out the element components corresponding to type of element.
1887 
1888  std::istringstream compositeDataStrm(compositeStr.c_str());
1889 
1890  try
1891  {
1892  bool first = true;
1893  std::string prevCompositeElementStr;
1894 
1895  while (!compositeDataStrm.fail())
1896  {
1897  std::string compositeElementStr;
1898  compositeDataStrm >> compositeElementStr;
1899 
1900  if (!compositeDataStrm.fail())
1901  {
1902  if (first)
1903  {
1904  first = false;
1905 
1906  CompositeSharedPtr curVector =
1908  m_meshComposites[indx] = curVector;
1909  }
1910 
1911  if (compositeElementStr.length() > 0)
1912  {
1913  ResolveGeomRef(prevCompositeElementStr,
1914  compositeElementStr,
1915  m_meshComposites[indx]);
1916  }
1917  prevCompositeElementStr = compositeElementStr;
1918  }
1919  }
1920  }
1921  catch (...)
1922  {
1923  NEKERROR(
1925  (std::string("Unable to read COMPOSITE data for composite: ") +
1926  compositeStr)
1927  .c_str());
1928  }
1929 
1930  /// Keep looking for additional composite definitions.
1931  node = node->NextSiblingElement("C");
1932  }
1933 
1934  ASSERTL0(nextCompositeNumber >= 0,
1935  "At least one composite must be specified.");
1936 }
#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
std::shared_ptr< Composite > CompositeSharedPtr
Definition: MeshGraph.h:136
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
void ResolveGeomRef(const std::string &prevToken, const std::string &token, CompositeSharedPtr &composite)

◆ ReadCurves()

void Nektar::SpatialDomains::MeshGraphXml::ReadCurves ( )
protectedvirtual

Look for elements in CURVE block.

All curves are of the form: "<? ID="#" TYPE="GLL OR other points type" NUMPOINTS="#"> ... </?>", with ? being an element type (either E or F).

These should be ordered.

Read id attribute.

Read edge id attribute.

Read text edgelement description.

Parse out the element components corresponding to type of element.

Read id attribute.

Read face id attribute.

Read text face element description.

Parse out the element components corresponding to type of element.

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 612 of file MeshGraphXml.cpp.

References ASSERTL0, Nektar::LibUtilities::Interpreter::DefineFunction(), Nektar::LibUtilities::Interpreter::Evaluate(), Nektar::StdRegions::find(), Nektar::LibUtilities::kPointsTypeStr, NEKERROR, and Nektar::LibUtilities::SIZE_PointsType.

613 {
614  // check to see if any scaling parameters are in
615  // attributes and determine these values
616  TiXmlElement *element = m_xmlGeom->FirstChildElement("VERTEX");
617  ASSERTL0(element, "Unable to find mesh VERTEX tag in file.");
618 
619  NekDouble xscale, yscale, zscale;
620 
621  LibUtilities::Interpreter expEvaluator;
622  const char *xscal = element->Attribute("XSCALE");
623  if (!xscal)
624  {
625  xscale = 1.0;
626  }
627  else
628  {
629  std::string xscalstr = xscal;
630  int expr_id = expEvaluator.DefineFunction("", xscalstr);
631  xscale = expEvaluator.Evaluate(expr_id);
632  }
633 
634  const char *yscal = element->Attribute("YSCALE");
635  if (!yscal)
636  {
637  yscale = 1.0;
638  }
639  else
640  {
641  std::string yscalstr = yscal;
642  int expr_id = expEvaluator.DefineFunction("", yscalstr);
643  yscale = expEvaluator.Evaluate(expr_id);
644  }
645 
646  const char *zscal = element->Attribute("ZSCALE");
647  if (!zscal)
648  {
649  zscale = 1.0;
650  }
651  else
652  {
653  std::string zscalstr = zscal;
654  int expr_id = expEvaluator.DefineFunction("", zscalstr);
655  zscale = expEvaluator.Evaluate(expr_id);
656  }
657 
658  NekDouble xmove, ymove, zmove;
659 
660  // check to see if any moving parameters are in
661  // attributes and determine these values
662 
663  const char *xmov = element->Attribute("XMOVE");
664  if (!xmov)
665  {
666  xmove = 0.0;
667  }
668  else
669  {
670  std::string xmovstr = xmov;
671  int expr_id = expEvaluator.DefineFunction("", xmovstr);
672  xmove = expEvaluator.Evaluate(expr_id);
673  }
674 
675  const char *ymov = element->Attribute("YMOVE");
676  if (!ymov)
677  {
678  ymove = 0.0;
679  }
680  else
681  {
682  std::string ymovstr = ymov;
683  int expr_id = expEvaluator.DefineFunction("", ymovstr);
684  ymove = expEvaluator.Evaluate(expr_id);
685  }
686 
687  const char *zmov = element->Attribute("ZMOVE");
688  if (!zmov)
689  {
690  zmove = 0.0;
691  }
692  else
693  {
694  std::string zmovstr = zmov;
695  int expr_id = expEvaluator.DefineFunction("", zmovstr);
696  zmove = expEvaluator.Evaluate(expr_id);
697  }
698 
699  int err;
700 
701  /// Look for elements in CURVE block.
702  TiXmlElement *field = m_xmlGeom->FirstChildElement("CURVED");
703 
704  if (!field) // return if no curved entities
705  {
706  return;
707  }
708 
709  /// All curves are of the form: "<? ID="#" TYPE="GLL OR other
710  /// points type" NUMPOINTS="#"> ... </?>", with ? being an
711  /// element type (either E or F).
712 
713  TiXmlElement *edgelement = field->FirstChildElement("E");
714 
715  int edgeindx, edgeid;
716  int nextEdgeNumber = -1;
717 
718  while (edgelement)
719  {
720  /// These should be ordered.
721  nextEdgeNumber++;
722 
723  std::string edge(edgelement->ValueStr());
724  ASSERTL0(edge == "E",
725  (std::string("Unknown 3D curve type:") + edge).c_str());
726 
727  /// Read id attribute.
728  err = edgelement->QueryIntAttribute("ID", &edgeindx);
729  ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute ID.");
730 
731  /// Read edge id attribute.
732  err = edgelement->QueryIntAttribute("EDGEID", &edgeid);
733  ASSERTL0(err == TIXML_SUCCESS,
734  "Unable to read curve attribute EDGEID.");
735 
736  /// Read text edgelement description.
737  std::string elementStr;
738  TiXmlNode *elementChild = edgelement->FirstChild();
739 
740  while (elementChild)
741  {
742  // Accumulate all non-comment element data
743  if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
744  {
745  elementStr += elementChild->ToText()->ValueStr();
746  elementStr += " ";
747  }
748  elementChild = elementChild->NextSibling();
749  }
750 
751  ASSERTL0(!elementStr.empty(), "Unable to read curve description body.");
752 
753  /// Parse out the element components corresponding to type of
754  /// element.
755  if (edge == "E")
756  {
757  int numPts = 0;
758  // Determine the points type
759  std::string typeStr = edgelement->Attribute("TYPE");
760  ASSERTL0(!typeStr.empty(), "TYPE must be specified in "
761  "points definition");
762 
764  const std::string *begStr = LibUtilities::kPointsTypeStr;
765  const std::string *endStr =
767  const std::string *ptsStr = std::find(begStr, endStr, typeStr);
768 
769  ASSERTL0(ptsStr != endStr, "Invalid points type.");
770  type = (LibUtilities::PointsType)(ptsStr - begStr);
771 
772  // Determine the number of points
773  err = edgelement->QueryIntAttribute("NUMPOINTS", &numPts);
774  ASSERTL0(err == TIXML_SUCCESS,
775  "Unable to read curve attribute NUMPOINTS.");
776  CurveSharedPtr curve(
778 
779  // Read points (x, y, z)
780  NekDouble xval, yval, zval;
781  std::istringstream elementDataStrm(elementStr.c_str());
782  try
783  {
784  while (!elementDataStrm.fail())
785  {
786  elementDataStrm >> xval >> yval >> zval;
787 
788  xval = xval * xscale + xmove;
789  yval = yval * yscale + ymove;
790  zval = zval * zscale + zmove;
791 
792  // Need to check it here because we may not be
793  // good after the read indicating that there
794  // was nothing to read.
795  if (!elementDataStrm.fail())
796  {
797  PointGeomSharedPtr vert(
799  m_meshDimension, edgeindx, xval, yval, zval));
800 
801  curve->m_points.push_back(vert);
802  }
803  }
804  }
805  catch (...)
806  {
808  (std::string("Unable to read curve data for EDGE: ") +
809  elementStr)
810  .c_str());
811  }
812 
813  ASSERTL0(curve->m_points.size() == numPts,
814  "Number of points specificed by attribute "
815  "NUMPOINTS is different from number of points "
816  "in list (edgeid = " +
817  boost::lexical_cast<string>(edgeid));
818 
819  m_curvedEdges[edgeid] = curve;
820 
821  edgelement = edgelement->NextSiblingElement("E");
822 
823  } // end if-loop
824 
825  } // end while-loop
826 
827  TiXmlElement *facelement = field->FirstChildElement("F");
828  int faceindx, faceid;
829 
830  while (facelement)
831  {
832  std::string face(facelement->ValueStr());
833  ASSERTL0(face == "F",
834  (std::string("Unknown 3D curve type: ") + face).c_str());
835 
836  /// Read id attribute.
837  err = facelement->QueryIntAttribute("ID", &faceindx);
838  ASSERTL0(err == TIXML_SUCCESS, "Unable to read curve attribute ID.");
839 
840  /// Read face id attribute.
841  err = facelement->QueryIntAttribute("FACEID", &faceid);
842  ASSERTL0(err == TIXML_SUCCESS,
843  "Unable to read curve attribute FACEID.");
844 
845  /// Read text face element description.
846  std::string elementStr;
847  TiXmlNode *elementChild = facelement->FirstChild();
848 
849  while (elementChild)
850  {
851  // Accumulate all non-comment element data
852  if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
853  {
854  elementStr += elementChild->ToText()->ValueStr();
855  elementStr += " ";
856  }
857  elementChild = elementChild->NextSibling();
858  }
859 
860  ASSERTL0(!elementStr.empty(), "Unable to read curve description body.");
861 
862  /// Parse out the element components corresponding to type of
863  /// element.
864  if (face == "F")
865  {
866  std::string typeStr = facelement->Attribute("TYPE");
867  ASSERTL0(!typeStr.empty(), "TYPE must be specified in "
868  "points definition");
870  const std::string *begStr = LibUtilities::kPointsTypeStr;
871  const std::string *endStr =
873  const std::string *ptsStr = std::find(begStr, endStr, typeStr);
874 
875  ASSERTL0(ptsStr != endStr, "Invalid points type.");
876  type = (LibUtilities::PointsType)(ptsStr - begStr);
877 
878  std::string numptsStr = facelement->Attribute("NUMPOINTS");
879  ASSERTL0(!numptsStr.empty(),
880  "NUMPOINTS must be specified in points definition");
881  int numPts = 0;
882  std::stringstream s;
883  s << numptsStr;
884  s >> numPts;
885 
886  CurveSharedPtr curve(
888 
889  ASSERTL0(numPts >= 3, "NUMPOINTS for face must be greater than 2");
890 
891  if (numPts == 3)
892  {
893  ASSERTL0(ptsStr != endStr, "Invalid points type.");
894  }
895 
896  // Read points (x, y, z)
897  NekDouble xval, yval, zval;
898  std::istringstream elementDataStrm(elementStr.c_str());
899  try
900  {
901  while (!elementDataStrm.fail())
902  {
903  elementDataStrm >> xval >> yval >> zval;
904 
905  // Need to check it here because we
906  // may not be good after the read
907  // indicating that there was nothing
908  // to read.
909  if (!elementDataStrm.fail())
910  {
911  PointGeomSharedPtr vert(
913  m_meshDimension, faceindx, xval, yval, zval));
914  curve->m_points.push_back(vert);
915  }
916  }
917  }
918  catch (...)
919  {
921  (std::string("Unable to read curve data for FACE: ") +
922  elementStr)
923  .c_str());
924  }
925  m_curvedFaces[faceid] = curve;
926 
927  facelement = facelement->NextSiblingElement("F");
928  }
929  }
930 }
#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
const std::string kPointsTypeStr[]
Definition: Foundations.hpp:70
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
double NekDouble
std::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:59
std::shared_ptr< Curve > CurveSharedPtr
Definition: Curve.hpp:61
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
Definition: StdRegions.hpp:358

◆ ReadDomain()

void Nektar::SpatialDomains::MeshGraphXml::ReadDomain ( )
protected

Look for data in DOMAIN block.

Elements are of the form: "<D ID = "N"> ... </D>". Read the ID field first.

Keep looking

Definition at line 932 of file MeshGraphXml.cpp.

References ASSERTL0.

933 {
934  TiXmlElement *domain = NULL;
935  /// Look for data in DOMAIN block.
936  domain = m_xmlGeom->FirstChildElement("DOMAIN");
937 
938  ASSERTL0(domain, "Unable to find DOMAIN tag in file.");
939 
940  /// Elements are of the form: "<D ID = "N"> ... </D>".
941  /// Read the ID field first.
942  TiXmlElement *multidomains = domain->FirstChildElement("D");
943 
944  if (multidomains)
945  {
946  int nextDomainNumber = 0;
947  while (multidomains)
948  {
949  int indx;
950  int err = multidomains->QueryIntAttribute("ID", &indx);
951  ASSERTL0(err == TIXML_SUCCESS,
952  "Unable to read attribute ID in Domain.");
953 
954  TiXmlNode *elementChild = multidomains->FirstChild();
955  while (elementChild &&
956  elementChild->Type() != TiXmlNode::TINYXML_TEXT)
957  {
958  elementChild = elementChild->NextSibling();
959  }
960 
961  ASSERTL0(elementChild, "Unable to read DOMAIN body.");
962  std::string elementStr = elementChild->ToText()->ValueStr();
963 
964  elementStr = elementStr.substr(elementStr.find_first_not_of(" "));
965 
966  std::string::size_type indxBeg = elementStr.find_first_of('[') + 1;
967  std::string::size_type indxEnd = elementStr.find_last_of(']') - 1;
968  std::string indxStr =
969  elementStr.substr(indxBeg, indxEnd - indxBeg + 1);
970 
971  ASSERTL0(
972  !indxStr.empty(),
973  "Unable to read domain's composite index (index missing?).");
974 
975  // Read the domain composites.
976  // Parse the composites into a list.
977  map<int, CompositeSharedPtr> unrollDomain;
978  GetCompositeList(indxStr, unrollDomain);
979  m_domain.push_back(unrollDomain);
980 
981  ASSERTL0(!m_domain[nextDomainNumber++].empty(),
982  (std::string(
983  "Unable to obtain domain's referenced composite: ") +
984  indxStr)
985  .c_str());
986 
987  /// Keep looking
988  multidomains = multidomains->NextSiblingElement("D");
989  }
990  }
991  else // previous definition of just one composite
992  {
993 
994  // find the non comment portion of the body.
995  TiXmlNode *elementChild = domain->FirstChild();
996  while (elementChild && elementChild->Type() != TiXmlNode::TINYXML_TEXT)
997  {
998  elementChild = elementChild->NextSibling();
999  }
1000 
1001  ASSERTL0(elementChild, "Unable to read DOMAIN body.");
1002  std::string elementStr = elementChild->ToText()->ValueStr();
1003 
1004  elementStr = elementStr.substr(elementStr.find_first_not_of(" "));
1005 
1006  std::string::size_type indxBeg = elementStr.find_first_of('[') + 1;
1007  std::string::size_type indxEnd = elementStr.find_last_of(']') - 1;
1008  std::string indxStr = elementStr.substr(indxBeg, indxEnd - indxBeg + 1);
1009 
1010  ASSERTL0(!indxStr.empty(),
1011  "Unable to read domain's composite index (index missing?).");
1012 
1013  // Read the domain composites.
1014  // Parse the composites into a list.
1015  map<int, CompositeSharedPtr> fullDomain;
1016  GetCompositeList(indxStr, fullDomain);
1017  m_domain.push_back(fullDomain);
1018 
1019  ASSERTL0(
1020  !m_domain[0].empty(),
1021  (std::string("Unable to obtain domain's referenced composite: ") +
1022  indxStr)
1023  .c_str());
1024  }
1025 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
std::vector< CompositeMap > m_domain
Definition: MeshGraph.h:457
void GetCompositeList(const std::string &compositeStr, CompositeMap &compositeVector) const
Definition: MeshGraph.cpp:599

◆ ReadEdges()

void Nektar::SpatialDomains::MeshGraphXml::ReadEdges ( )
protectedvirtual

Look for elements in ELEMENT block.

All elements are of the form: "<E ID="#"> ... </E>", with ? being the element type. Read the ID field first.

Since all edge data is one big text block, we need to accumulate all TINYXML_TEXT data and then parse it. This approach effectively skips all comments or other node types since we only care about the edge list. We cannot handle missing edge numbers as we could with missing element numbers due to the text block format.

Now parse out the edges, three fields at a time.

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 1027 of file MeshGraphXml.cpp.

References ASSERTL0, and NEKERROR.

1028 {
1029  CurveMap::iterator it;
1030 
1031  /// Look for elements in ELEMENT block.
1032  TiXmlElement *field = m_xmlGeom->FirstChildElement("EDGE");
1033 
1034  ASSERTL0(field, "Unable to find EDGE tag in file.");
1035 
1036  /// All elements are of the form: "<E ID="#"> ... </E>", with
1037  /// ? being the element type.
1038  /// Read the ID field first.
1039  TiXmlElement *edge = field->FirstChildElement("E");
1040 
1041  /// Since all edge data is one big text block, we need to accumulate
1042  /// all TINYXML_TEXT data and then parse it. This approach effectively
1043  /// skips
1044  /// all comments or other node types since we only care about the
1045  /// edge list. We cannot handle missing edge numbers as we could
1046  /// with missing element numbers due to the text block format.
1047  std::string edgeStr;
1048  int indx;
1049 
1050  while (edge)
1051  {
1052  int err = edge->QueryIntAttribute("ID", &indx);
1053  ASSERTL0(err == TIXML_SUCCESS, "Unable to read edge attribute ID.");
1054 
1055  TiXmlNode *child = edge->FirstChild();
1056  edgeStr.clear();
1057  if (child->Type() == TiXmlNode::TINYXML_TEXT)
1058  {
1059  edgeStr += child->ToText()->ValueStr();
1060  }
1061 
1062  /// Now parse out the edges, three fields at a time.
1063  int vertex1, vertex2;
1064  std::istringstream edgeDataStrm(edgeStr.c_str());
1065 
1066  try
1067  {
1068  while (!edgeDataStrm.fail())
1069  {
1070  edgeDataStrm >> vertex1 >> vertex2;
1071 
1072  // Must check after the read because we
1073  // may be at the end and not know it. If
1074  // we are at the end we will add a
1075  // duplicate of the last entry if we don't
1076  // check here.
1077  if (!edgeDataStrm.fail())
1078  {
1079  PointGeomSharedPtr vertices[2] = {GetVertex(vertex1),
1080  GetVertex(vertex2)};
1081  SegGeomSharedPtr edge;
1082  it = m_curvedEdges.find(indx);
1083 
1084  if (it == m_curvedEdges.end())
1085  {
1087  indx, m_spaceDimension, vertices);
1088  }
1089  else
1090  {
1092  indx, m_spaceDimension, vertices, it->second);
1093  }
1094 
1095  m_segGeoms[indx] = edge;
1096  }
1097  }
1098  }
1099  catch (...)
1100  {
1101  NEKERROR(
1103  (std::string("Unable to read edge data: ") + edgeStr).c_str());
1104  }
1105 
1106  edge = edge->NextSiblingElement("E");
1107  }
1108 }
#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
PointGeomSharedPtr GetVertex(int id)
Definition: MeshGraph.h:328
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:59
std::shared_ptr< SegGeom > SegGeomSharedPtr
Definition: Geometry2D.h:62

◆ ReadElements()

void Nektar::SpatialDomains::MeshGraphXml::ReadElements ( )
protected

Definition at line 1255 of file MeshGraphXml.cpp.

1256 {
1257  switch (m_meshDimension)
1258  {
1259  case 1:
1260  ReadElements1D();
1261  break;
1262  case 2:
1263  ReadElements2D();
1264  break;
1265  case 3:
1266  ReadElements3D();
1267  break;
1268  }
1269 }

◆ ReadElements1D()

void Nektar::SpatialDomains::MeshGraphXml::ReadElements1D ( )
protectedvirtual

Look for elements in ELEMENT block.

All elements are of the form: "<S ID = n> ... </S>", with ? being the element type.

Parse out the element components corresponding to type of element. Read two vertex numbers

Keep looking for additional segments

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 1271 of file MeshGraphXml.cpp.

References ASSERTL0, and NEKERROR.

1272 {
1273  TiXmlElement *field = NULL;
1274 
1275  /// Look for elements in ELEMENT block.
1276  field = m_xmlGeom->FirstChildElement("ELEMENT");
1277 
1278  ASSERTL0(field, "Unable to find ELEMENT tag in file.");
1279 
1280  /// All elements are of the form: "<S ID = n> ... </S>", with
1281  /// ? being the element type.
1282 
1283  TiXmlElement *segment = field->FirstChildElement("S");
1284  CurveMap::iterator it;
1285 
1286  while (segment)
1287  {
1288  int indx;
1289  int err = segment->QueryIntAttribute("ID", &indx);
1290  ASSERTL0(err == TIXML_SUCCESS, "Unable to read element attribute ID.");
1291 
1292  TiXmlNode *elementChild = segment->FirstChild();
1293  while (elementChild && elementChild->Type() != TiXmlNode::TINYXML_TEXT)
1294  {
1295  elementChild = elementChild->NextSibling();
1296  }
1297 
1298  ASSERTL0(elementChild, "Unable to read element description body.");
1299  std::string elementStr = elementChild->ToText()->ValueStr();
1300 
1301  /// Parse out the element components corresponding to type of
1302  /// element.
1303  /// Read two vertex numbers
1304  int vertex1, vertex2;
1305  std::istringstream elementDataStrm(elementStr.c_str());
1306 
1307  try
1308  {
1309  elementDataStrm >> vertex1;
1310  elementDataStrm >> vertex2;
1311 
1312  ASSERTL0(!elementDataStrm.fail(),
1313  (std::string("Unable to read element data for SEGMENT: ") +
1314  elementStr)
1315  .c_str());
1316 
1317  PointGeomSharedPtr vertices[2] = {GetVertex(vertex1),
1318  GetVertex(vertex2)};
1319  SegGeomSharedPtr seg;
1320  it = m_curvedEdges.find(indx);
1321 
1322  if (it == m_curvedEdges.end())
1323  {
1325  indx, m_spaceDimension, vertices);
1326  seg->SetGlobalID(indx); // Set global mesh id
1327  }
1328  else
1329  {
1331  indx, m_spaceDimension, vertices, it->second);
1332  seg->SetGlobalID(indx); // Set global mesh id
1333  }
1334  seg->SetGlobalID(indx);
1335  m_segGeoms[indx] = seg;
1336  }
1337  catch (...)
1338  {
1340  (std::string("Unable to read element data for segment: ") +
1341  elementStr)
1342  .c_str());
1343  }
1344  /// Keep looking for additional segments
1345  segment = segment->NextSiblingElement("S");
1346  }
1347 }
#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
PointGeomSharedPtr GetVertex(int id)
Definition: MeshGraph.h:328
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:59
std::shared_ptr< SegGeom > SegGeomSharedPtr
Definition: Geometry2D.h:62

◆ ReadElements2D()

void Nektar::SpatialDomains::MeshGraphXml::ReadElements2D ( )
protectedvirtual

Look for elements in ELEMENT block.

All elements are of the form: "<? ID="#"> ... </?>", with ? being the element type.

Read id attribute.

Read text element description.

Parse out the element components corresponding to type of element.

Create a TriGeom to hold the new definition.

Create a QuadGeom to hold the new definition.

Keep looking

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 1349 of file MeshGraphXml.cpp.

References ASSERTL0, and NEKERROR.

1350 {
1351  /// Look for elements in ELEMENT block.
1352  TiXmlElement *field = m_xmlGeom->FirstChildElement("ELEMENT");
1353 
1354  ASSERTL0(field, "Unable to find ELEMENT tag in file.");
1355 
1356  // Set up curve map for curved elements on an embedded manifold.
1357  CurveMap::iterator it;
1358 
1359  /// All elements are of the form: "<? ID="#"> ... </?>", with
1360  /// ? being the element type.
1361 
1362  TiXmlElement *element = field->FirstChildElement();
1363 
1364  while (element)
1365  {
1366  std::string elementType(element->ValueStr());
1367 
1368  ASSERTL0(
1369  elementType == "Q" || elementType == "T",
1370  (std::string("Unknown 2D element type: ") + elementType).c_str());
1371 
1372  /// Read id attribute.
1373  int indx;
1374  int err = element->QueryIntAttribute("ID", &indx);
1375  ASSERTL0(err == TIXML_SUCCESS, "Unable to read element attribute ID.");
1376 
1377  it = m_curvedFaces.find(indx);
1378 
1379  /// Read text element description.
1380  TiXmlNode *elementChild = element->FirstChild();
1381  std::string elementStr;
1382  while (elementChild)
1383  {
1384  if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
1385  {
1386  elementStr += elementChild->ToText()->ValueStr();
1387  }
1388  elementChild = elementChild->NextSibling();
1389  }
1390 
1391  ASSERTL0(!elementStr.empty(),
1392  "Unable to read element description body.");
1393 
1394  /// Parse out the element components corresponding to type of
1395  /// element.
1396  if (elementType == "T")
1397  {
1398  // Read three edge numbers
1399  int edge1, edge2, edge3;
1400  std::istringstream elementDataStrm(elementStr.c_str());
1401 
1402  try
1403  {
1404  elementDataStrm >> edge1;
1405  elementDataStrm >> edge2;
1406  elementDataStrm >> edge3;
1407 
1408  ASSERTL0(
1409  !elementDataStrm.fail(),
1410  (std::string("Unable to read element data for TRIANGLE: ") +
1411  elementStr)
1412  .c_str());
1413 
1414  /// Create a TriGeom to hold the new definition.
1416  GetSegGeom(edge1), GetSegGeom(edge2), GetSegGeom(edge3)};
1417 
1418  TriGeomSharedPtr trigeom;
1419  if (it == m_curvedFaces.end())
1420  {
1421  trigeom =
1423  }
1424  else
1425  {
1427  indx, edges, it->second);
1428  }
1429  trigeom->SetGlobalID(indx);
1430 
1431  m_triGeoms[indx] = trigeom;
1432  }
1433  catch (...)
1434  {
1435  NEKERROR(
1437  (std::string("Unable to read element data for TRIANGLE: ") +
1438  elementStr)
1439  .c_str());
1440  }
1441  }
1442  else if (elementType == "Q")
1443  {
1444  // Read four edge numbers
1445  int edge1, edge2, edge3, edge4;
1446  std::istringstream elementDataStrm(elementStr.c_str());
1447 
1448  try
1449  {
1450  elementDataStrm >> edge1;
1451  elementDataStrm >> edge2;
1452  elementDataStrm >> edge3;
1453  elementDataStrm >> edge4;
1454 
1455  ASSERTL0(
1456  !elementDataStrm.fail(),
1457  (std::string("Unable to read element data for QUAD: ") +
1458  elementStr)
1459  .c_str());
1460 
1461  /// Create a QuadGeom to hold the new definition.
1463  GetSegGeom(edge1), GetSegGeom(edge2), GetSegGeom(edge3),
1464  GetSegGeom(edge4)};
1465 
1466  QuadGeomSharedPtr quadgeom;
1467  if (it == m_curvedFaces.end())
1468  {
1469  quadgeom =
1471  }
1472  else
1473  {
1475  indx, edges, it->second);
1476  }
1477  quadgeom->SetGlobalID(indx);
1478 
1479  m_quadGeoms[indx] = quadgeom;
1480  }
1481  catch (...)
1482  {
1483  NEKERROR(
1485  (std::string("Unable to read element data for QUAD: ") +
1486  elementStr)
1487  .c_str());
1488  }
1489  }
1490  /// Keep looking
1491  element = element->NextSiblingElement();
1492  }
1493 }
#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
static const int kNedges
Definition: QuadGeom.h:78
std::shared_ptr< QuadGeom > QuadGeomSharedPtr
Definition: HexGeom.h:46
SegGeomSharedPtr GetSegGeom(int id)
Definition: MeshGraph.h:333
std::shared_ptr< TriGeom > TriGeomSharedPtr
Definition: TriGeom.h:58
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static const int kNedges
Get the orientation of face1.
Definition: TriGeom.h:73
std::shared_ptr< SegGeom > SegGeomSharedPtr
Definition: Geometry2D.h:62

◆ ReadElements3D()

void Nektar::SpatialDomains::MeshGraphXml::ReadElements3D ( )
protectedvirtual

Look for elements in ELEMENT block.

All elements are of the form: "<? ID="#"> ... </?>", with ? being the element type.

Read id attribute.

Read text element description.

Parse out the element components corresponding to type of element.

Create arrays for the tri and quad faces.

Fill the arrays and make sure there aren't too many faces.

Make sure all of the face indicies could be read, and that there weren't too few.

Create arrays for the tri and quad faces.

Fill the arrays and make sure there aren't too many faces.

Make sure all of the face indicies could be read, and that there weren't too few.

Create arrays for the tri and quad faces.

Fill the arrays and make sure there aren't too many faces.

Make sure all of the face indicies could be read, and that there weren't too few.

Create arrays for the tri and quad faces.

Fill the arrays and make sure there aren't too many faces.

Make sure all of the face indicies could be read, and that there weren't too few.

Keep looking

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 1495 of file MeshGraphXml.cpp.

References ASSERTL0, Nektar::LibUtilities::eQuadrilateral, Nektar::LibUtilities::eTriangle, and NEKERROR.

1496 {
1497  /// Look for elements in ELEMENT block.
1498  TiXmlElement *field = m_xmlGeom->FirstChildElement("ELEMENT");
1499 
1500  ASSERTL0(field, "Unable to find ELEMENT tag in file.");
1501 
1502  /// All elements are of the form: "<? ID="#"> ... </?>", with
1503  /// ? being the element type.
1504 
1505  TiXmlElement *element = field->FirstChildElement();
1506 
1507  while (element)
1508  {
1509  std::string elementType(element->ValueStr());
1510 
1511  // A - tet, P - pyramid, R - prism, H - hex
1512  ASSERTL0(
1513  elementType == "A" || elementType == "P" || elementType == "R" ||
1514  elementType == "H",
1515  (std::string("Unknown 3D element type: ") + elementType).c_str());
1516 
1517  /// Read id attribute.
1518  int indx;
1519  int err = element->QueryIntAttribute("ID", &indx);
1520  ASSERTL0(err == TIXML_SUCCESS, "Unable to read element attribute ID.");
1521 
1522  /// Read text element description.
1523  TiXmlNode *elementChild = element->FirstChild();
1524  std::string elementStr;
1525  while (elementChild)
1526  {
1527  if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
1528  {
1529  elementStr += elementChild->ToText()->ValueStr();
1530  }
1531  elementChild = elementChild->NextSibling();
1532  }
1533 
1534  ASSERTL0(!elementStr.empty(),
1535  "Unable to read element description body.");
1536 
1537  std::istringstream elementDataStrm(elementStr.c_str());
1538 
1539  /// Parse out the element components corresponding to type of
1540  /// element.
1541 
1542  // Tetrahedral
1543  if (elementType == "A")
1544  {
1545  try
1546  {
1547  /// Create arrays for the tri and quad faces.
1548  const int kNfaces = TetGeom::kNfaces;
1549  const int kNtfaces = TetGeom::kNtfaces;
1550  const int kNqfaces = TetGeom::kNqfaces;
1551  TriGeomSharedPtr tfaces[kNtfaces];
1552  int Ntfaces = 0;
1553  int Nqfaces = 0;
1554 
1555  /// Fill the arrays and make sure there aren't too many
1556  /// faces.
1557  std::stringstream errorstring;
1558  errorstring << "Element " << indx << " must have " << kNtfaces
1559  << " triangle face(s), and " << kNqfaces
1560  << " quadrilateral face(s).";
1561  for (int i = 0; i < kNfaces; i++)
1562  {
1563  int faceID;
1564  elementDataStrm >> faceID;
1565  Geometry2DSharedPtr face = GetGeometry2D(faceID);
1566  if (face == Geometry2DSharedPtr() ||
1567  (face->GetShapeType() != LibUtilities::eTriangle &&
1568  face->GetShapeType() != LibUtilities::eQuadrilateral))
1569  {
1570  std::stringstream errorstring;
1571  errorstring << "Element " << indx
1572  << " has invalid face: " << faceID;
1573  ASSERTL0(false, errorstring.str().c_str());
1574  }
1575  else if (face->GetShapeType() == LibUtilities::eTriangle)
1576  {
1577  ASSERTL0(Ntfaces < kNtfaces, errorstring.str().c_str());
1578  tfaces[Ntfaces++] =
1579  static_pointer_cast<TriGeom>(face);
1580  }
1581  else if (face->GetShapeType() ==
1583  {
1584  ASSERTL0(Nqfaces < kNqfaces, errorstring.str().c_str());
1585  }
1586  }
1587 
1588  /// Make sure all of the face indicies could be read, and
1589  /// that there weren't too few.
1590  ASSERTL0(!elementDataStrm.fail(),
1591  (std::string(
1592  "Unable to read element data for TETRAHEDRON: ") +
1593  elementStr)
1594  .c_str());
1595  ASSERTL0(Ntfaces == kNtfaces, errorstring.str().c_str());
1596  ASSERTL0(Nqfaces == kNqfaces, errorstring.str().c_str());
1597 
1598  TetGeomSharedPtr tetgeom(
1600 
1601  m_tetGeoms[indx] = tetgeom;
1602  PopulateFaceToElMap(tetgeom, kNfaces);
1603  }
1604  catch (...)
1605  {
1607  (std::string(
1608  "Unable to read element data for TETRAHEDRON: ") +
1609  elementStr)
1610  .c_str());
1611  }
1612  }
1613  // Pyramid
1614  else if (elementType == "P")
1615  {
1616  try
1617  {
1618  /// Create arrays for the tri and quad faces.
1619  const int kNfaces = PyrGeom::kNfaces;
1620  const int kNtfaces = PyrGeom::kNtfaces;
1621  const int kNqfaces = PyrGeom::kNqfaces;
1622  Geometry2DSharedPtr faces[kNfaces];
1623  int Nfaces = 0;
1624  int Ntfaces = 0;
1625  int Nqfaces = 0;
1626 
1627  /// Fill the arrays and make sure there aren't too many
1628  /// faces.
1629  std::stringstream errorstring;
1630  errorstring << "Element " << indx << " must have " << kNtfaces
1631  << " triangle face(s), and " << kNqfaces
1632  << " quadrilateral face(s).";
1633  for (int i = 0; i < kNfaces; i++)
1634  {
1635  int faceID;
1636  elementDataStrm >> faceID;
1637  Geometry2DSharedPtr face = GetGeometry2D(faceID);
1638  if (face == Geometry2DSharedPtr() ||
1639  (face->GetShapeType() != LibUtilities::eTriangle &&
1640  face->GetShapeType() != LibUtilities::eQuadrilateral))
1641  {
1642  std::stringstream errorstring;
1643  errorstring << "Element " << indx
1644  << " has invalid face: " << faceID;
1645  ASSERTL0(false, errorstring.str().c_str());
1646  }
1647  else if (face->GetShapeType() == LibUtilities::eTriangle)
1648  {
1649  ASSERTL0(Ntfaces < kNtfaces, errorstring.str().c_str());
1650  faces[Nfaces++] =
1651  static_pointer_cast<TriGeom>(face);
1652  Ntfaces++;
1653  }
1654  else if (face->GetShapeType() ==
1656  {
1657  ASSERTL0(Nqfaces < kNqfaces, errorstring.str().c_str());
1658  faces[Nfaces++] =
1659  static_pointer_cast<QuadGeom>(face);
1660  Nqfaces++;
1661  }
1662  }
1663 
1664  /// Make sure all of the face indicies could be read, and
1665  /// that there weren't too few.
1666  ASSERTL0(
1667  !elementDataStrm.fail(),
1668  (std::string("Unable to read element data for PYRAMID: ") +
1669  elementStr)
1670  .c_str());
1671  ASSERTL0(Ntfaces == kNtfaces, errorstring.str().c_str());
1672  ASSERTL0(Nqfaces == kNqfaces, errorstring.str().c_str());
1673 
1674  PyrGeomSharedPtr pyrgeom(
1676 
1677  m_pyrGeoms[indx] = pyrgeom;
1678  PopulateFaceToElMap(pyrgeom, kNfaces);
1679  }
1680  catch (...)
1681  {
1682  NEKERROR(
1684  (std::string("Unable to read element data for PYRAMID: ") +
1685  elementStr)
1686  .c_str());
1687  }
1688  }
1689  // Prism
1690  else if (elementType == "R")
1691  {
1692  try
1693  {
1694  /// Create arrays for the tri and quad faces.
1695  const int kNfaces = PrismGeom::kNfaces;
1696  const int kNtfaces = PrismGeom::kNtfaces;
1697  const int kNqfaces = PrismGeom::kNqfaces;
1698  Geometry2DSharedPtr faces[kNfaces];
1699  int Ntfaces = 0;
1700  int Nqfaces = 0;
1701  int Nfaces = 0;
1702 
1703  /// Fill the arrays and make sure there aren't too many
1704  /// faces.
1705  std::stringstream errorstring;
1706  errorstring << "Element " << indx << " must have " << kNtfaces
1707  << " triangle face(s), and " << kNqfaces
1708  << " quadrilateral face(s).";
1709 
1710  for (int i = 0; i < kNfaces; i++)
1711  {
1712  int faceID;
1713  elementDataStrm >> faceID;
1714  Geometry2DSharedPtr face = GetGeometry2D(faceID);
1715  if (face == Geometry2DSharedPtr() ||
1716  (face->GetShapeType() != LibUtilities::eTriangle &&
1717  face->GetShapeType() != LibUtilities::eQuadrilateral))
1718  {
1719  std::stringstream errorstring;
1720  errorstring << "Element " << indx
1721  << " has invalid face: " << faceID;
1722  ASSERTL0(false, errorstring.str().c_str());
1723  }
1724  else if (face->GetShapeType() == LibUtilities::eTriangle)
1725  {
1726  ASSERTL0(Ntfaces < kNtfaces, errorstring.str().c_str());
1727  faces[Nfaces++] =
1728  std::static_pointer_cast<TriGeom>(face);
1729  Ntfaces++;
1730  }
1731  else if (face->GetShapeType() ==
1733  {
1734  ASSERTL0(Nqfaces < kNqfaces, errorstring.str().c_str());
1735  faces[Nfaces++] =
1736  std::static_pointer_cast<QuadGeom>(face);
1737  Nqfaces++;
1738  }
1739  }
1740 
1741  /// Make sure all of the face indicies could be read, and
1742  /// that there weren't too few.
1743  ASSERTL0(
1744  !elementDataStrm.fail(),
1745  (std::string("Unable to read element data for PRISM: ") +
1746  elementStr)
1747  .c_str());
1748  ASSERTL0(Ntfaces == kNtfaces, errorstring.str().c_str());
1749  ASSERTL0(Nqfaces == kNqfaces, errorstring.str().c_str());
1750 
1751  PrismGeomSharedPtr prismgeom(
1753 
1754  m_prismGeoms[indx] = prismgeom;
1755  PopulateFaceToElMap(prismgeom, kNfaces);
1756  }
1757  catch (...)
1758  {
1759  NEKERROR(
1761  (std::string("Unable to read element data for PRISM: ") +
1762  elementStr)
1763  .c_str());
1764  }
1765  }
1766  // Hexahedral
1767  else if (elementType == "H")
1768  {
1769  try
1770  {
1771  /// Create arrays for the tri and quad faces.
1772  const int kNfaces = HexGeom::kNfaces;
1773  const int kNtfaces = HexGeom::kNtfaces;
1774  const int kNqfaces = HexGeom::kNqfaces;
1775  // TriGeomSharedPtr tfaces[kNtfaces];
1776  QuadGeomSharedPtr qfaces[kNqfaces];
1777  int Ntfaces = 0;
1778  int Nqfaces = 0;
1779 
1780  /// Fill the arrays and make sure there aren't too many
1781  /// faces.
1782  std::stringstream errorstring;
1783  errorstring << "Element " << indx << " must have " << kNtfaces
1784  << " triangle face(s), and " << kNqfaces
1785  << " quadrilateral face(s).";
1786  for (int i = 0; i < kNfaces; i++)
1787  {
1788  int faceID;
1789  elementDataStrm >> faceID;
1790  Geometry2DSharedPtr face = GetGeometry2D(faceID);
1791  if (face == Geometry2DSharedPtr() ||
1792  (face->GetShapeType() != LibUtilities::eTriangle &&
1793  face->GetShapeType() != LibUtilities::eQuadrilateral))
1794  {
1795  std::stringstream errorstring;
1796  errorstring << "Element " << indx
1797  << " has invalid face: " << faceID;
1798  ASSERTL0(false, errorstring.str().c_str());
1799  }
1800  else if (face->GetShapeType() == LibUtilities::eTriangle)
1801  {
1802  ASSERTL0(Ntfaces < kNtfaces, errorstring.str().c_str());
1803  // tfaces[Ntfaces++] =
1804  // boost::static_pointer_cast<TriGeom>(face);
1805  }
1806  else if (face->GetShapeType() ==
1808  {
1809  ASSERTL0(Nqfaces < kNqfaces, errorstring.str().c_str());
1810  qfaces[Nqfaces++] =
1811  std::static_pointer_cast<QuadGeom>(face);
1812  }
1813  }
1814 
1815  /// Make sure all of the face indicies could be read, and
1816  /// that there weren't too few.
1817  ASSERTL0(!elementDataStrm.fail(),
1818  (std::string(
1819  "Unable to read element data for HEXAHEDRAL: ") +
1820  elementStr)
1821  .c_str());
1822  ASSERTL0(Ntfaces == kNtfaces, errorstring.str().c_str());
1823  ASSERTL0(Nqfaces == kNqfaces, errorstring.str().c_str());
1824 
1825  HexGeomSharedPtr hexgeom(
1827 
1828  m_hexGeoms[indx] = hexgeom;
1829  PopulateFaceToElMap(hexgeom, kNfaces);
1830  }
1831  catch (...)
1832  {
1834  (std::string(
1835  "Unable to read element data for HEXAHEDRAL: ") +
1836  elementStr)
1837  .c_str());
1838  }
1839  }
1840  /// Keep looking
1841  element = element->NextSiblingElement();
1842  }
1843 }
#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
void PopulateFaceToElMap(Geometry3DSharedPtr element, int kNfaces)
Given a 3D geometry object #element, populate the face to element map m_faceToElMap which maps faces ...
Definition: MeshGraph.cpp:3502
std::shared_ptr< Geometry2D > Geometry2DSharedPtr
Definition: Geometry.h:65
static const int kNfaces
Definition: PyrGeom.h:57
std::shared_ptr< TetGeom > TetGeomSharedPtr
Definition: TetGeom.h:88
Geometry2DSharedPtr GetGeometry2D(int gID)
Definition: MeshGraph.h:382
static const int kNtfaces
Definition: HexGeom.h:59
std::shared_ptr< QuadGeom > QuadGeomSharedPtr
Definition: HexGeom.h:46
static const int kNfaces
Definition: HexGeom.h:60
static const int kNtfaces
Definition: TetGeom.h:57
static const int kNfaces
Definition: TetGeom.h:58
std::shared_ptr< TriGeom > TriGeomSharedPtr
Definition: TriGeom.h:58
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static const int kNqfaces
Definition: TetGeom.h:56
static const int kNtfaces
Definition: PyrGeom.h:56
std::shared_ptr< PyrGeom > PyrGeomSharedPtr
Definition: PyrGeom.h:80
static const int kNqfaces
Definition: PyrGeom.h:55
std::shared_ptr< HexGeom > HexGeomSharedPtr
Definition: HexGeom.h:90
static const int kNqfaces
Definition: HexGeom.h:58
std::shared_ptr< PrismGeom > PrismGeomSharedPtr
Definition: PrismGeom.h:88

◆ ReadFaces()

void Nektar::SpatialDomains::MeshGraphXml::ReadFaces ( )
protectedvirtual

Look for elements in FACE block.

All faces are of the form: "<? ID="#"> ... </?>", with ? being an element type (either Q or T). They might be in compressed format and so then need upacking.

Read id attribute.

See if this face has curves.

Read text element description.

Parse out the element components corresponding to type of element.

Create a TriGeom to hold the new definition.

Create a QuadGeom to hold the new definition.

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 1110 of file MeshGraphXml.cpp.

References ASSERTL0, and NEKERROR.

1111 {
1112  /// Look for elements in FACE block.
1113  TiXmlElement *field = m_xmlGeom->FirstChildElement("FACE");
1114 
1115  ASSERTL0(field, "Unable to find FACE tag in file.");
1116 
1117  /// All faces are of the form: "<? ID="#"> ... </?>", with
1118  /// ? being an element type (either Q or T).
1119  /// They might be in compressed format and so then need upacking.
1120 
1121  TiXmlElement *element = field->FirstChildElement();
1122  CurveMap::iterator it;
1123 
1124  while (element)
1125  {
1126  std::string elementType(element->ValueStr());
1127 
1128  ASSERTL0(elementType == "Q" || elementType == "T",
1129  (std::string("Unknown 3D face type: ") + elementType).c_str());
1130 
1131  /// Read id attribute.
1132  int indx;
1133  int err = element->QueryIntAttribute("ID", &indx);
1134  ASSERTL0(err == TIXML_SUCCESS, "Unable to read face attribute ID.");
1135 
1136  /// See if this face has curves.
1137  it = m_curvedFaces.find(indx);
1138 
1139  /// Read text element description.
1140  TiXmlNode *elementChild = element->FirstChild();
1141  std::string elementStr;
1142  while (elementChild)
1143  {
1144  if (elementChild->Type() == TiXmlNode::TINYXML_TEXT)
1145  {
1146  elementStr += elementChild->ToText()->ValueStr();
1147  }
1148  elementChild = elementChild->NextSibling();
1149  }
1150 
1151  ASSERTL0(!elementStr.empty(), "Unable to read face description body.");
1152 
1153  /// Parse out the element components corresponding to type of
1154  /// element.
1155  if (elementType == "T")
1156  {
1157  // Read three edge numbers
1158  int edge1, edge2, edge3;
1159  std::istringstream elementDataStrm(elementStr.c_str());
1160 
1161  try
1162  {
1163  elementDataStrm >> edge1;
1164  elementDataStrm >> edge2;
1165  elementDataStrm >> edge3;
1166 
1167  ASSERTL0(
1168  !elementDataStrm.fail(),
1169  (std::string("Unable to read face data for TRIANGLE: ") +
1170  elementStr)
1171  .c_str());
1172 
1173  /// Create a TriGeom to hold the new definition.
1175  GetSegGeom(edge1), GetSegGeom(edge2), GetSegGeom(edge3)};
1176 
1177  TriGeomSharedPtr trigeom;
1178 
1179  if (it == m_curvedFaces.end())
1180  {
1181  trigeom =
1183  }
1184  else
1185  {
1187  indx, edges, it->second);
1188  }
1189 
1190  trigeom->SetGlobalID(indx);
1191 
1192  m_triGeoms[indx] = trigeom;
1193  }
1194  catch (...)
1195  {
1196  NEKERROR(
1198  (std::string("Unable to read face data for TRIANGLE: ") +
1199  elementStr)
1200  .c_str());
1201  }
1202  }
1203  else if (elementType == "Q")
1204  {
1205  // Read four edge numbers
1206  int edge1, edge2, edge3, edge4;
1207  std::istringstream elementDataStrm(elementStr.c_str());
1208 
1209  try
1210  {
1211  elementDataStrm >> edge1;
1212  elementDataStrm >> edge2;
1213  elementDataStrm >> edge3;
1214  elementDataStrm >> edge4;
1215 
1216  ASSERTL0(!elementDataStrm.fail(),
1217  (std::string("Unable to read face data for QUAD: ") +
1218  elementStr)
1219  .c_str());
1220 
1221  /// Create a QuadGeom to hold the new definition.
1223  GetSegGeom(edge1), GetSegGeom(edge2), GetSegGeom(edge3),
1224  GetSegGeom(edge4)};
1225 
1226  QuadGeomSharedPtr quadgeom;
1227 
1228  if (it == m_curvedFaces.end())
1229  {
1230  quadgeom =
1232  }
1233  else
1234  {
1236  indx, edges, it->second);
1237  }
1238  quadgeom->SetGlobalID(indx);
1239 
1240  m_quadGeoms[indx] = quadgeom;
1241  }
1242  catch (...)
1243  {
1245  (std::string("Unable to read face data for QUAD: ") +
1246  elementStr)
1247  .c_str());
1248  }
1249  }
1250  // Keep looking
1251  element = element->NextSiblingElement();
1252  }
1253 }
#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
static const int kNedges
Definition: QuadGeom.h:78
std::shared_ptr< QuadGeom > QuadGeomSharedPtr
Definition: HexGeom.h:46
SegGeomSharedPtr GetSegGeom(int id)
Definition: MeshGraph.h:333
std::shared_ptr< TriGeom > TriGeomSharedPtr
Definition: TriGeom.h:58
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static const int kNedges
Get the orientation of face1.
Definition: TriGeom.h:73
std::shared_ptr< SegGeom > SegGeomSharedPtr
Definition: Geometry2D.h:62

◆ ReadGeometry()

void Nektar::SpatialDomains::MeshGraphXml::ReadGeometry ( DomainRangeShPtr  rng,
bool  fillGraph 
)
virtual

Error value returned by TinyXML.

Implements Nektar::SpatialDomains::MeshGraph.

Definition at line 362 of file MeshGraphXml.cpp.

References ASSERTL0.

365 {
366  // Reset member variables.
367  m_vertSet.clear();
368  m_curvedEdges.clear();
369  m_curvedFaces.clear();
370  m_segGeoms.clear();
371  m_triGeoms.clear();
372  m_quadGeoms.clear();
373  m_tetGeoms.clear();
374  m_pyrGeoms.clear();
375  m_prismGeoms.clear();
376  m_hexGeoms.clear();
377  m_meshComposites.clear();
378  m_compositesLabels.clear();
379  m_domain.clear();
380  m_expansionMapShPtrMap.clear();
381  m_geomInfo.clear();
382  m_faceToElMap.clear();
383 
384  m_domainRange = rng;
385  m_xmlGeom = m_session->GetElement("NEKTAR/GEOMETRY");
386 
387  int err; /// Error value returned by TinyXML.
388 
389  TiXmlAttribute *attr = m_xmlGeom->FirstAttribute();
390 
391  // Initialize the mesh and space dimensions to 3 dimensions.
392  // We want to do this each time we read a file, so it should
393  // be done here and not just during class initialization.
394  m_meshPartitioned = false;
395  m_meshDimension = 3;
396  m_spaceDimension = 3;
397 
398  while (attr)
399  {
400  std::string attrName(attr->Name());
401  if (attrName == "DIM")
402  {
403  err = attr->QueryIntValue(&m_meshDimension);
404  ASSERTL0(err == TIXML_SUCCESS, "Unable to read mesh dimension.");
405  }
406  else if (attrName == "SPACE")
407  {
408  err = attr->QueryIntValue(&m_spaceDimension);
409  ASSERTL0(err == TIXML_SUCCESS, "Unable to read space dimension.");
410  }
411  else if (attrName == "PARTITION")
412  {
413  err = attr->QueryIntValue(&m_partition);
414  ASSERTL0(err == TIXML_SUCCESS, "Unable to read partition.");
415  m_meshPartitioned = true;
416  }
417  else
418  {
419  std::string errstr("Unknown attribute: ");
420  errstr += attrName;
421  ASSERTL0(false, errstr.c_str());
422  }
423 
424  // Get the next attribute.
425  attr = attr->Next();
426  }
427 
429  "Mesh dimension greater than space dimension");
430 
431  ReadVertices();
432  ReadCurves();
433  if (m_meshDimension >= 2)
434  {
435  ReadEdges();
436  if (m_meshDimension == 3)
437  {
438  ReadFaces();
439  }
440  }
441  ReadElements();
442  ReadComposites();
443  ReadDomain();
444 
445  if (fillGraph)
446  {
448  }
449 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
LibUtilities::SessionReaderSharedPtr m_session
Definition: MeshGraph.h:435
std::map< int, std::string > m_compositesLabels
Definition: MeshGraph.h:456
DomainRangeShPtr m_domainRange
Definition: MeshGraph.h:458
std::unordered_map< int, GeometryLinkSharedPtr > m_faceToElMap
Definition: MeshGraph.h:464
std::vector< CompositeMap > m_domain
Definition: MeshGraph.h:457
ExpansionMapShPtrMap m_expansionMapShPtrMap
Definition: MeshGraph.h:460

◆ ReadVertices()

void Nektar::SpatialDomains::MeshGraphXml::ReadVertices ( )
protectedvirtual

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 451 of file MeshGraphXml.cpp.

References ASSERTL0, Nektar::LibUtilities::Interpreter::DefineFunction(), and Nektar::LibUtilities::Interpreter::Evaluate().

452 {
453  // Now read the vertices
454  TiXmlElement *element = m_xmlGeom->FirstChildElement("VERTEX");
455  ASSERTL0(element, "Unable to find mesh VERTEX tag in file.");
456 
457  NekDouble xscale, yscale, zscale;
458 
459  // check to see if any scaling parameters are in
460  // attributes and determine these values
461  LibUtilities::Interpreter expEvaluator;
462  const char *xscal = element->Attribute("XSCALE");
463  if (!xscal)
464  {
465  xscale = 1.0;
466  }
467  else
468  {
469  std::string xscalstr = xscal;
470  int expr_id = expEvaluator.DefineFunction("", xscalstr);
471  xscale = expEvaluator.Evaluate(expr_id);
472  }
473 
474  const char *yscal = element->Attribute("YSCALE");
475  if (!yscal)
476  {
477  yscale = 1.0;
478  }
479  else
480  {
481  std::string yscalstr = yscal;
482  int expr_id = expEvaluator.DefineFunction("", yscalstr);
483  yscale = expEvaluator.Evaluate(expr_id);
484  }
485 
486  const char *zscal = element->Attribute("ZSCALE");
487  if (!zscal)
488  {
489  zscale = 1.0;
490  }
491  else
492  {
493  std::string zscalstr = zscal;
494  int expr_id = expEvaluator.DefineFunction("", zscalstr);
495  zscale = expEvaluator.Evaluate(expr_id);
496  }
497 
498  NekDouble xmove, ymove, zmove;
499 
500  // check to see if any moving parameters are in
501  // attributes and determine these values
502 
503  const char *xmov = element->Attribute("XMOVE");
504  if (!xmov)
505  {
506  xmove = 0.0;
507  }
508  else
509  {
510  std::string xmovstr = xmov;
511  int expr_id = expEvaluator.DefineFunction("", xmovstr);
512  xmove = expEvaluator.Evaluate(expr_id);
513  }
514 
515  const char *ymov = element->Attribute("YMOVE");
516  if (!ymov)
517  {
518  ymove = 0.0;
519  }
520  else
521  {
522  std::string ymovstr = ymov;
523  int expr_id = expEvaluator.DefineFunction("", ymovstr);
524  ymove = expEvaluator.Evaluate(expr_id);
525  }
526 
527  const char *zmov = element->Attribute("ZMOVE");
528  if (!zmov)
529  {
530  zmove = 0.0;
531  }
532  else
533  {
534  std::string zmovstr = zmov;
535  int expr_id = expEvaluator.DefineFunction("", zmovstr);
536  zmove = expEvaluator.Evaluate(expr_id);
537  }
538 
539  TiXmlElement *vertex = element->FirstChildElement("V");
540 
541  int indx;
542  int nextVertexNumber = -1;
543 
544  while (vertex)
545  {
546  nextVertexNumber++;
547 
548  TiXmlAttribute *vertexAttr = vertex->FirstAttribute();
549  std::string attrName(vertexAttr->Name());
550 
551  ASSERTL0(attrName == "ID",
552  (std::string("Unknown attribute name: ") + attrName).c_str());
553 
554  int err = vertexAttr->QueryIntValue(&indx);
555  ASSERTL0(err == TIXML_SUCCESS, "Unable to read attribute ID.");
556 
557  // Now read body of vertex
558  std::string vertexBodyStr;
559 
560  TiXmlNode *vertexBody = vertex->FirstChild();
561 
562  while (vertexBody)
563  {
564  // Accumulate all non-comment body data.
565  if (vertexBody->Type() == TiXmlNode::TINYXML_TEXT)
566  {
567  vertexBodyStr += vertexBody->ToText()->Value();
568  vertexBodyStr += " ";
569  }
570 
571  vertexBody = vertexBody->NextSibling();
572  }
573 
574  ASSERTL0(!vertexBodyStr.empty(),
575  "Vertex definitions must contain vertex data.");
576 
577  // Get vertex data from the data string.
578  NekDouble xval, yval, zval;
579  std::istringstream vertexDataStrm(vertexBodyStr.c_str());
580 
581  try
582  {
583  while (!vertexDataStrm.fail())
584  {
585  vertexDataStrm >> xval >> yval >> zval;
586 
587  xval = xval * xscale + xmove;
588  yval = yval * yscale + ymove;
589  zval = zval * zscale + zmove;
590 
591  // Need to check it here because we may not be
592  // good after the read indicating that there
593  // was nothing to read.
594  if (!vertexDataStrm.fail())
595  {
596  PointGeomSharedPtr vert(
598  m_spaceDimension, indx, xval, yval, zval));
599  m_vertSet[indx] = vert;
600  }
601  }
602  }
603  catch (...)
604  {
605  ASSERTL0(false, "Unable to read VERTEX data.");
606  }
607 
608  vertex = vertex->NextSiblingElement("V");
609  }
610 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
double NekDouble
std::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:59

◆ ResolveGeomRef()

void Nektar::SpatialDomains::MeshGraphXml::ResolveGeomRef ( const std::string &  prevToken,
const std::string &  token,
CompositeSharedPtr composite 
)
protected

Definition at line 1938 of file MeshGraphXml.cpp.

1941 {
1942  switch (m_meshDimension)
1943  {
1944  case 1:
1945  ResolveGeomRef1D(prevToken, token, composite);
1946  break;
1947  case 2:
1948  ResolveGeomRef2D(prevToken, token, composite);
1949  break;
1950  case 3:
1951  ResolveGeomRef3D(prevToken, token, composite);
1952  break;
1953  }
1954 }
void ResolveGeomRef3D(const std::string &prevToken, const std::string &token, CompositeSharedPtr &composite)
void ResolveGeomRef2D(const std::string &prevToken, const std::string &token, CompositeSharedPtr &composite)
void ResolveGeomRef1D(const std::string &prevToken, const std::string &token, CompositeSharedPtr &composite)

◆ ResolveGeomRef1D()

void Nektar::SpatialDomains::MeshGraphXml::ResolveGeomRef1D ( const std::string &  prevToken,
const std::string &  token,
CompositeSharedPtr composite 
)
protected

Definition at line 1956 of file MeshGraphXml.cpp.

References ASSERTL0, and NEKERROR.

1959 {
1960  try
1961  {
1962  std::istringstream tokenStream(token);
1963  std::istringstream prevTokenStream(prevToken);
1964 
1965  char type;
1966  char prevType;
1967 
1968  tokenStream >> type;
1969 
1970  std::string::size_type indxBeg = token.find_first_of('[') + 1;
1971  std::string::size_type indxEnd = token.find_last_of(']') - 1;
1972 
1973  ASSERTL0(
1974  indxBeg <= indxEnd,
1975  (std::string("Error reading index definition:") + token).c_str());
1976 
1977  std::string indxStr = token.substr(indxBeg, indxEnd - indxBeg + 1);
1978 
1979  typedef vector<unsigned int> SeqVectorType;
1980  SeqVectorType seqVector;
1981 
1982  if (!ParseUtils::GenerateSeqVector(indxStr.c_str(), seqVector))
1983  {
1985  (std::string("Ill-formed sequence definition: ") + indxStr)
1986  .c_str());
1987  }
1988 
1989  prevTokenStream >> prevType;
1990 
1991  // All composites must be of the same dimension.
1992  bool validSequence =
1993  (prevToken.empty() || // No previous, then current is just fine.
1994  (type == 'V' && prevType == 'V') ||
1995  (type == 'S' && prevType == 'S'));
1996 
1997  ASSERTL0(validSequence,
1998  (std::string("Invalid combination of composite items: ") +
1999  type + " and " + prevType + ".")
2000  .c_str());
2001 
2002  switch (type)
2003  {
2004  case 'V': // Vertex
2005  for (SeqVectorType::iterator iter = seqVector.begin();
2006  iter != seqVector.end(); ++iter)
2007  {
2008  if (m_vertSet.find(*iter) == m_vertSet.end())
2009  {
2010  char errStr[16] = "";
2011  ::sprintf(errStr, "%d", *iter);
2012  NEKERROR(
2014  (std::string("Unknown vertex index: ") + errStr)
2015  .c_str());
2016  }
2017  else
2018  {
2019  composite->m_geomVec.push_back(m_vertSet[*iter]);
2020  }
2021  }
2022  break;
2023 
2024  case 'S': // Segment
2025  for (SeqVectorType::iterator iter = seqVector.begin();
2026  iter != seqVector.end(); ++iter)
2027  {
2028  if (m_segGeoms.find(*iter) == m_segGeoms.end())
2029  {
2030  char errStr[16] = "";
2031  ::sprintf(errStr, "%d", *iter);
2032  NEKERROR(
2034  (std::string("Unknown segment index: ") + errStr)
2035  .c_str());
2036  }
2037  else
2038  {
2039  composite->m_geomVec.push_back(m_segGeoms[*iter]);
2040  }
2041  }
2042  break;
2043 
2044  default:
2046  (std::string("Unrecognized composite token: ") + token)
2047  .c_str());
2048  }
2049  }
2050  catch (...)
2051  {
2053  (std::string("Problem processing composite token: ") + token)
2054  .c_str());
2055  }
2056 
2057  return;
2058 }
#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
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector. ...
Definition: ParseUtils.cpp:108

◆ ResolveGeomRef2D()

void Nektar::SpatialDomains::MeshGraphXml::ResolveGeomRef2D ( const std::string &  prevToken,
const std::string &  token,
CompositeSharedPtr composite 
)
protected

Definition at line 2060 of file MeshGraphXml.cpp.

References ASSERTL0, and NEKERROR.

2063 {
2064  try
2065  {
2066  std::istringstream tokenStream(token);
2067  std::istringstream prevTokenStream(prevToken);
2068 
2069  char type;
2070  char prevType;
2071 
2072  tokenStream >> type;
2073 
2074  std::string::size_type indxBeg = token.find_first_of('[') + 1;
2075  std::string::size_type indxEnd = token.find_last_of(']') - 1;
2076 
2077  ASSERTL0(
2078  indxBeg <= indxEnd,
2079  (std::string("Error reading index definition:") + token).c_str());
2080 
2081  std::string indxStr = token.substr(indxBeg, indxEnd - indxBeg + 1);
2082  std::vector<unsigned int> seqVector;
2083  std::vector<unsigned int>::iterator seqIter;
2084 
2085  bool err = ParseUtils::GenerateSeqVector(indxStr.c_str(), seqVector);
2086 
2087  ASSERTL0(err,
2088  (std::string("Error reading composite elements: ") + indxStr)
2089  .c_str());
2090 
2091  prevTokenStream >> prevType;
2092 
2093  // All composites must be of the same dimension.
2094  bool validSequence =
2095  (prevToken.empty() || // No previous, then current is just fine.
2096  (type == 'V' && prevType == 'V') ||
2097  (type == 'E' && prevType == 'E') ||
2098  ((type == 'T' || type == 'Q') &&
2099  (prevType == 'T' || prevType == 'Q')));
2100 
2101  ASSERTL0(validSequence,
2102  (std::string("Invalid combination of composite items: ") +
2103  type + " and " + prevType + ".")
2104  .c_str());
2105 
2106  switch (type)
2107  {
2108  case 'E': // Edge
2109  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2110  ++seqIter)
2111  {
2112  if (m_segGeoms.find(*seqIter) == m_segGeoms.end())
2113  {
2114  char errStr[16] = "";
2115  ::sprintf(errStr, "%d", *seqIter);
2117  (std::string("Unknown edge index: ") + errStr)
2118  .c_str());
2119  }
2120  else
2121  {
2122  composite->m_geomVec.push_back(m_segGeoms[*seqIter]);
2123  }
2124  }
2125  break;
2126 
2127  case 'T': // Triangle
2128  {
2129  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2130  ++seqIter)
2131  {
2132  if (m_triGeoms.count(*seqIter) == 0)
2133  {
2134  char errStr[16] = "";
2135  ::sprintf(errStr, "%d", *seqIter);
2136  NEKERROR(
2138  (std::string("Unknown triangle index: ") + errStr)
2139  .c_str());
2140  }
2141  else
2142  {
2143  if (CheckRange(*m_triGeoms[*seqIter]))
2144  {
2145  composite->m_geomVec.push_back(
2146  m_triGeoms[*seqIter]);
2147  }
2148  }
2149  }
2150  }
2151  break;
2152 
2153  case 'Q': // Quad
2154  {
2155  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2156  ++seqIter)
2157  {
2158  if (m_quadGeoms.count(*seqIter) == 0)
2159  {
2160  char errStr[16] = "";
2161  ::sprintf(errStr, "%d", *seqIter);
2163  (std::string("Unknown quad index: ") + errStr +
2164  std::string(" in Composite section"))
2165  .c_str());
2166  }
2167  else
2168  {
2169  if (CheckRange(*m_quadGeoms[*seqIter]))
2170  {
2171  composite->m_geomVec.push_back(
2172  m_quadGeoms[*seqIter]);
2173  }
2174  }
2175  }
2176  }
2177  break;
2178 
2179  case 'V': // Vertex
2180  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2181  ++seqIter)
2182  {
2183  if (*seqIter >= m_vertSet.size())
2184  {
2185  char errStr[16] = "";
2186  ::sprintf(errStr, "%d", *seqIter);
2187  NEKERROR(
2189  (std::string("Unknown vertex index: ") + errStr)
2190  .c_str());
2191  }
2192  else
2193  {
2194  composite->m_geomVec.push_back(m_vertSet[*seqIter]);
2195  }
2196  }
2197  break;
2198 
2199  default:
2201  (std::string("Unrecognized composite token: ") + token)
2202  .c_str());
2203  }
2204  }
2205  catch (...)
2206  {
2208  (std::string("Problem processing composite token: ") + token)
2209  .c_str());
2210  }
2211 
2212  return;
2213 }
#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
bool CheckRange(Geometry2D &geom)
Check if goemetry is in range definition if activated.
Definition: MeshGraph.cpp:352
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector. ...
Definition: ParseUtils.cpp:108

◆ ResolveGeomRef3D()

void Nektar::SpatialDomains::MeshGraphXml::ResolveGeomRef3D ( const std::string &  prevToken,
const std::string &  token,
CompositeSharedPtr composite 
)
protected

Definition at line 2215 of file MeshGraphXml.cpp.

References ASSERTL0, and NEKERROR.

2218 {
2219  try
2220  {
2221  std::istringstream tokenStream(token);
2222  std::istringstream prevTokenStream(prevToken);
2223 
2224  char type;
2225  char prevType;
2226 
2227  tokenStream >> type;
2228 
2229  std::string::size_type indxBeg = token.find_first_of('[') + 1;
2230  std::string::size_type indxEnd = token.find_last_of(']') - 1;
2231 
2232  ASSERTL0(
2233  indxBeg <= indxEnd,
2234  (std::string("Error reading index definition:") + token).c_str());
2235 
2236  std::string indxStr = token.substr(indxBeg, indxEnd - indxBeg + 1);
2237 
2238  std::vector<unsigned int> seqVector;
2239  std::vector<unsigned int>::iterator seqIter;
2240 
2241  bool err = ParseUtils::GenerateSeqVector(indxStr.c_str(), seqVector);
2242 
2243  ASSERTL0(err,
2244  (std::string("Error reading composite elements: ") + indxStr)
2245  .c_str());
2246 
2247  prevTokenStream >> prevType;
2248 
2249  // All composites must be of the same dimension. This map makes things
2250  // clean to compare.
2251  map<char, int> typeMap;
2252  typeMap['V'] = 1; // Vertex
2253  typeMap['E'] = 1; // Edge
2254  typeMap['T'] = 2; // Triangle
2255  typeMap['Q'] = 2; // Quad
2256  typeMap['A'] = 3; // Tet
2257  typeMap['P'] = 3; // Pyramid
2258  typeMap['R'] = 3; // Prism
2259  typeMap['H'] = 3; // Hex
2260 
2261  // Make sure only geoms of the same dimension are combined.
2262  bool validSequence =
2263  (prevToken.empty() || (typeMap[type] == typeMap[prevType]));
2264 
2265  ASSERTL0(validSequence,
2266  (std::string("Invalid combination of composite items: ") +
2267  type + " and " + prevType + ".")
2268  .c_str());
2269 
2270  switch (type)
2271  {
2272  case 'V': // Vertex
2273  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2274  ++seqIter)
2275  {
2276  if (m_vertSet.find(*seqIter) == m_vertSet.end())
2277  {
2278  char errStr[16] = "";
2279  ::sprintf(errStr, "%d", *seqIter);
2280  NEKERROR(
2282  (std::string("Unknown vertex index: ") + errStr)
2283  .c_str());
2284  }
2285  else
2286  {
2287  composite->m_geomVec.push_back(m_vertSet[*seqIter]);
2288  }
2289  }
2290  break;
2291 
2292  case 'E': // Edge
2293  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2294  ++seqIter)
2295  {
2296  if (m_segGeoms.find(*seqIter) == m_segGeoms.end())
2297  {
2298  char errStr[16] = "";
2299  ::sprintf(errStr, "%d", *seqIter);
2301  (std::string("Unknown edge index: ") + errStr)
2302  .c_str());
2303  }
2304  else
2305  {
2306  composite->m_geomVec.push_back(m_segGeoms[*seqIter]);
2307  }
2308  }
2309  break;
2310 
2311  case 'F': // Face
2312  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2313  ++seqIter)
2314  {
2315  Geometry2DSharedPtr face = GetGeometry2D(*seqIter);
2316  if (face == Geometry2DSharedPtr())
2317  {
2318  char errStr[16] = "";
2319  ::sprintf(errStr, "%d", *seqIter);
2321  (std::string("Unknown face index: ") + errStr)
2322  .c_str());
2323  }
2324  else
2325  {
2326  if (CheckRange(*face))
2327  {
2328  composite->m_geomVec.push_back(face);
2329  }
2330  }
2331  }
2332  break;
2333 
2334  case 'T': // Triangle
2335  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2336  ++seqIter)
2337  {
2338  if (m_triGeoms.find(*seqIter) == m_triGeoms.end())
2339  {
2340  char errStr[16] = "";
2341  ::sprintf(errStr, "%d", *seqIter);
2342  NEKERROR(
2344  (std::string("Unknown triangle index: ") + errStr)
2345  .c_str());
2346  }
2347  else
2348  {
2349  if (CheckRange(*m_triGeoms[*seqIter]))
2350  {
2351  composite->m_geomVec.push_back(
2352  m_triGeoms[*seqIter]);
2353  }
2354  }
2355  }
2356  break;
2357 
2358  case 'Q': // Quad
2359  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2360  ++seqIter)
2361  {
2362  if (m_quadGeoms.find(*seqIter) == m_quadGeoms.end())
2363  {
2364  char errStr[16] = "";
2365  ::sprintf(errStr, "%d", *seqIter);
2367  (std::string("Unknown quad index: ") + errStr)
2368  .c_str());
2369  }
2370  else
2371  {
2372  if (CheckRange(*m_quadGeoms[*seqIter]))
2373  {
2374  composite->m_geomVec.push_back(
2375  m_quadGeoms[*seqIter]);
2376  }
2377  }
2378  }
2379  break;
2380 
2381  // Tetrahedron
2382  case 'A':
2383  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2384  ++seqIter)
2385  {
2386  if (m_tetGeoms.find(*seqIter) == m_tetGeoms.end())
2387  {
2388  char errStr[16] = "";
2389  ::sprintf(errStr, "%d", *seqIter);
2391  (std::string("Unknown tet index: ") + errStr)
2392  .c_str());
2393  }
2394  else
2395  {
2396  if (CheckRange(*m_tetGeoms[*seqIter]))
2397  {
2398  composite->m_geomVec.push_back(
2399  m_tetGeoms[*seqIter]);
2400  }
2401  }
2402  }
2403  break;
2404 
2405  // Pyramid
2406  case 'P':
2407  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2408  ++seqIter)
2409  {
2410  if (m_pyrGeoms.find(*seqIter) == m_pyrGeoms.end())
2411  {
2412  char errStr[16] = "";
2413  ::sprintf(errStr, "%d", *seqIter);
2414  NEKERROR(
2416  (std::string("Unknown pyramid index: ") + errStr)
2417  .c_str());
2418  }
2419  else
2420  {
2421  if (CheckRange(*m_pyrGeoms[*seqIter]))
2422  {
2423  composite->m_geomVec.push_back(
2424  m_pyrGeoms[*seqIter]);
2425  }
2426  }
2427  }
2428  break;
2429 
2430  // Prism
2431  case 'R':
2432  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2433  ++seqIter)
2434  {
2435  if (m_prismGeoms.find(*seqIter) == m_prismGeoms.end())
2436  {
2437  char errStr[16] = "";
2438  ::sprintf(errStr, "%d", *seqIter);
2440  (std::string("Unknown prism index: ") + errStr)
2441  .c_str());
2442  }
2443  else
2444  {
2445  if (CheckRange(*m_prismGeoms[*seqIter]))
2446  {
2447  composite->m_geomVec.push_back(
2448  m_prismGeoms[*seqIter]);
2449  }
2450  }
2451  }
2452  break;
2453 
2454  // Hex
2455  case 'H':
2456  for (seqIter = seqVector.begin(); seqIter != seqVector.end();
2457  ++seqIter)
2458  {
2459  if (m_hexGeoms.find(*seqIter) == m_hexGeoms.end())
2460  {
2461  char errStr[16] = "";
2462  ::sprintf(errStr, "%d", *seqIter);
2464  (std::string("Unknown hex index: ") + errStr)
2465  .c_str());
2466  }
2467  else
2468  {
2469  if (CheckRange(*m_hexGeoms[*seqIter]))
2470  {
2471  composite->m_geomVec.push_back(
2472  m_hexGeoms[*seqIter]);
2473  }
2474  }
2475  }
2476  break;
2477 
2478  default:
2480  (std::string("Unrecognized composite token: ") + token)
2481  .c_str());
2482  }
2483  }
2484  catch (...)
2485  {
2487  (std::string("Problem processing composite token: ") + token)
2488  .c_str());
2489  }
2490 
2491  return;
2492 }
#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
std::shared_ptr< Geometry2D > Geometry2DSharedPtr
Definition: Geometry.h:65
Geometry2DSharedPtr GetGeometry2D(int gID)
Definition: MeshGraph.h:382
bool CheckRange(Geometry2D &geom)
Check if goemetry is in range definition if activated.
Definition: MeshGraph.cpp:352
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector. ...
Definition: ParseUtils.cpp:108

◆ WriteComposites()

void Nektar::SpatialDomains::MeshGraphXml::WriteComposites ( TiXmlElement *  geomTag,
CompositeMap comps 
)
protected

Definition at line 2689 of file MeshGraphXml.cpp.

2690 {
2691  TiXmlElement *compTag = new TiXmlElement("COMPOSITE");
2692 
2693  for (auto &cIt : comps)
2694  {
2695  if (cIt.second->m_geomVec.size() == 0)
2696  {
2697  continue;
2698  }
2699 
2700  TiXmlElement *c = new TiXmlElement("C");
2701  c->SetAttribute("ID", cIt.first);
2702  c->LinkEndChild(new TiXmlText(GetCompositeString(cIt.second)));
2703  compTag->LinkEndChild(c);
2704  }
2705 
2706  geomTag->LinkEndChild(compTag);
2707 }
std::string GetCompositeString(CompositeSharedPtr comp)
Returns a string representation of a composite.
Definition: MeshGraph.cpp:2606

◆ WriteCurves()

void Nektar::SpatialDomains::MeshGraphXml::WriteCurves ( TiXmlElement *  geomTag,
CurveMap edges,
CurveMap faces 
)
protectedvirtual

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 2635 of file MeshGraphXml.cpp.

References Nektar::LibUtilities::kPointsTypeStr, and CellMLToNektar.cellml_metadata::p.

2637 {
2638  TiXmlElement *curveTag = new TiXmlElement("CURVED");
2639  CurveMap::iterator curveIt;
2640  int curveId = 0;
2641 
2642  for (curveIt = edges.begin(); curveIt != edges.end(); ++curveIt)
2643  {
2644  CurveSharedPtr curve = curveIt->second;
2645  TiXmlElement *c = new TiXmlElement("E");
2646  stringstream s;
2647  s.precision(8);
2648 
2649  for (int j = 0; j < curve->m_points.size(); ++j)
2650  {
2651  SpatialDomains::PointGeomSharedPtr p = curve->m_points[j];
2652  s << scientific << (*p)(0) << " " << (*p)(1) << " " << (*p)(2)
2653  << " ";
2654  }
2655 
2656  c->SetAttribute("ID", curveId++);
2657  c->SetAttribute("EDGEID", curve->m_curveID);
2658  c->SetAttribute("NUMPOINTS", curve->m_points.size());
2659  c->SetAttribute("TYPE", LibUtilities::kPointsTypeStr[curve->m_ptype]);
2660  c->LinkEndChild(new TiXmlText(s.str()));
2661  curveTag->LinkEndChild(c);
2662  }
2663 
2664  for (curveIt = faces.begin(); curveIt != faces.end(); ++curveIt)
2665  {
2666  CurveSharedPtr curve = curveIt->second;
2667  TiXmlElement *c = new TiXmlElement("F");
2668  stringstream s;
2669  s.precision(8);
2670 
2671  for (int j = 0; j < curve->m_points.size(); ++j)
2672  {
2673  SpatialDomains::PointGeomSharedPtr p = curve->m_points[j];
2674  s << scientific << (*p)(0) << " " << (*p)(1) << " " << (*p)(2)
2675  << " ";
2676  }
2677 
2678  c->SetAttribute("ID", curveId++);
2679  c->SetAttribute("FACEID", curve->m_curveID);
2680  c->SetAttribute("NUMPOINTS", curve->m_points.size());
2681  c->SetAttribute("TYPE", LibUtilities::kPointsTypeStr[curve->m_ptype]);
2682  c->LinkEndChild(new TiXmlText(s.str()));
2683  curveTag->LinkEndChild(c);
2684  }
2685 
2686  geomTag->LinkEndChild(curveTag);
2687 }
const std::string kPointsTypeStr[]
Definition: Foundations.hpp:70
std::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:59
std::shared_ptr< Curve > CurveSharedPtr
Definition: Curve.hpp:61

◆ WriteDefaultExpansion()

void Nektar::SpatialDomains::MeshGraphXml::WriteDefaultExpansion ( TiXmlElement *  root)
protected

Definition at line 2727 of file MeshGraphXml.cpp.

2728 {
2729  TiXmlElement *expTag = new TiXmlElement("EXPANSIONS");
2730 
2731  for (auto it = m_meshComposites.begin(); it != m_meshComposites.end(); it++)
2732  {
2733  if (it->second->m_geomVec[0]->GetShapeDim() == m_meshDimension)
2734  {
2735  TiXmlElement *exp = new TiXmlElement("E");
2736  exp->SetAttribute("COMPOSITE",
2737  "C[" + boost::lexical_cast<string>(it->first) +
2738  "]");
2739  exp->SetAttribute("NUMMODES", 4);
2740  exp->SetAttribute("TYPE", "MODIFIED");
2741  exp->SetAttribute("FIELDS", "u");
2742 
2743  expTag->LinkEndChild(exp);
2744  }
2745  }
2746  root->LinkEndChild(expTag);
2747 }

◆ WriteDomain()

void Nektar::SpatialDomains::MeshGraphXml::WriteDomain ( TiXmlElement *  geomTag,
std::vector< CompositeMap > &  domain 
)
protected

Definition at line 2709 of file MeshGraphXml.cpp.

2711 {
2712  TiXmlElement *domTag = new TiXmlElement("DOMAIN");
2713  stringstream domString;
2714 
2715  // @todo Fix this to accomodate multi domain output
2716  vector<unsigned int> idxList;
2717  for (auto cIt = domain[0].begin(); cIt != domain[0].end(); ++cIt)
2718  {
2719  idxList.push_back(cIt->first);
2720  }
2721 
2722  domString << " C[" << ParseUtils::GenerateSeqString(idxList) << "] ";
2723  domTag->LinkEndChild(new TiXmlText(domString.str()));
2724  geomTag->LinkEndChild(domTag);
2725 }
static std::string GenerateSeqString(const std::vector< T > &v)
Generate a compressed comma-separated string representation of a vector of unsigned integers...
Definition: ParseUtils.h:71

◆ WriteEdges()

void Nektar::SpatialDomains::MeshGraphXml::WriteEdges ( TiXmlElement *  geomTag,
SegGeomMap edges 
)
protectedvirtual

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 2512 of file MeshGraphXml.cpp.

2513 {
2514  TiXmlElement *edgeTag =
2515  new TiXmlElement(m_meshDimension == 1 ? "ELEMENT" : "EDGE");
2516  string tag = m_meshDimension == 1 ? "S" : "E";
2517 
2518  for (auto &i : edges)
2519  {
2520  stringstream s;
2521  SegGeomSharedPtr seg = i.second;
2522  s << seg->GetVid(0) << " " << seg->GetVid(1);
2523  TiXmlElement *e = new TiXmlElement(tag);
2524  e->SetAttribute("ID", i.first);
2525  e->LinkEndChild(new TiXmlText(s.str()));
2526  edgeTag->LinkEndChild(e);
2527  }
2528 
2529  geomTag->LinkEndChild(edgeTag);
2530 }
std::shared_ptr< SegGeom > SegGeomSharedPtr
Definition: Geometry2D.h:62

◆ WriteGeometry()

void Nektar::SpatialDomains::MeshGraphXml::WriteGeometry ( std::string &  outfilename,
bool  defaultExp = false,
const LibUtilities::FieldMetaDataMap metadata = LibUtilities::NullFieldMetaDataMap 
)
virtual

Write out an XML file containing the GEOMETRY block representing this MeshGraph instance inside a NEKTAR tag.

Implements Nektar::SpatialDomains::MeshGraph.

Definition at line 2753 of file MeshGraphXml.cpp.

Referenced by ~MeshGraphXml().

2757 {
2758  // Create empty TinyXML document.
2759  TiXmlDocument doc;
2760  TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
2761  doc.LinkEndChild(decl);
2762 
2763  TiXmlElement *root = new TiXmlElement("NEKTAR");
2764  doc.LinkEndChild(root);
2765  TiXmlElement *geomTag = new TiXmlElement("GEOMETRY");
2766  root->LinkEndChild(geomTag);
2767 
2768  // Add provenance information using FieldIO library.
2771  new LibUtilities::XmlTagWriter(root)),
2772  metadata);
2773 
2774  // Update attributes with dimensions.
2775  geomTag->SetAttribute("DIM", m_meshDimension);
2776  geomTag->SetAttribute("SPACE", m_spaceDimension);
2777 
2778  // Clear existing elements.
2779  geomTag->Clear();
2780 
2781  // Write out informatio
2782  WriteVertices(geomTag, m_vertSet);
2783  WriteEdges(geomTag, m_segGeoms);
2784  if (m_meshDimension > 1)
2785  {
2786  TiXmlElement *faceTag =
2787  new TiXmlElement(m_meshDimension == 2 ? "ELEMENT" : "FACE");
2788 
2789  WriteTris(faceTag, m_triGeoms);
2790  WriteQuads(faceTag, m_quadGeoms);
2791  geomTag->LinkEndChild(faceTag);
2792  }
2793  if (m_meshDimension > 2)
2794  {
2795  TiXmlElement *elmtTag = new TiXmlElement("ELEMENT");
2796 
2797  WriteHexs(elmtTag, m_hexGeoms);
2798  WritePyrs(elmtTag, m_pyrGeoms);
2799  WritePrisms(elmtTag, m_prismGeoms);
2800  WriteTets(elmtTag, m_tetGeoms);
2801 
2802  geomTag->LinkEndChild(elmtTag);
2803  }
2806  WriteDomain(geomTag, m_domain);
2807 
2808  if (defaultExp)
2809  {
2810  WriteDefaultExpansion(root);
2811  }
2812 
2813  // Save file.
2814  doc.SaveFile(outfilename);
2815 }
void WriteComposites(TiXmlElement *geomTag, CompositeMap &comps)
virtual void WriteHexs(TiXmlElement *elmtTag, HexGeomMap &hexs)
virtual void WriteEdges(TiXmlElement *geomTag, SegGeomMap &edges)
virtual void WriteTris(TiXmlElement *faceTag, TriGeomMap &tris)
virtual void WritePyrs(TiXmlElement *elmtTag, PyrGeomMap &pyrs)
virtual void WriteTets(TiXmlElement *elmtTag, TetGeomMap &tets)
virtual void WriteVertices(TiXmlElement *geomTag, PointGeomMap &verts)
void WriteDomain(TiXmlElement *geomTag, std::vector< CompositeMap > &domain)
virtual void WriteQuads(TiXmlElement *faceTag, QuadGeomMap &quads)
virtual void WritePrisms(TiXmlElement *elmtTag, PrismGeomMap &pris)
std::shared_ptr< XmlTagWriter > XmlTagWriterSharedPtr
Definition: FieldIOXml.h:163
std::vector< CompositeMap > m_domain
Definition: MeshGraph.h:457
void WriteDefaultExpansion(TiXmlElement *root)
static void AddInfoTag(TagWriterSharedPtr root, const FieldMetaDataMap &fieldmetadatamap)
Add provenance information to the field metadata map.
Definition: FieldIO.cpp:348
virtual void WriteCurves(TiXmlElement *geomTag, CurveMap &edges, CurveMap &faces)

◆ WriteHexs()

void Nektar::SpatialDomains::MeshGraphXml::WriteHexs ( TiXmlElement *  elmtTag,
HexGeomMap hexs 
)
protectedvirtual

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 2565 of file MeshGraphXml.cpp.

2566 {
2567  string tag = "H";
2568 
2569  for (auto &i : hexs)
2570  {
2571  stringstream s;
2572  HexGeomSharedPtr hex = i.second;
2573  s << hex->GetFid(0) << " " << hex->GetFid(1) << " " << hex->GetFid(2)
2574  << " " << hex->GetFid(3) << " " << hex->GetFid(4) << " "
2575  << hex->GetFid(5) << " ";
2576  TiXmlElement *h = new TiXmlElement(tag);
2577  h->SetAttribute("ID", i.first);
2578  h->LinkEndChild(new TiXmlText(s.str()));
2579  elmtTag->LinkEndChild(h);
2580  }
2581 }
std::shared_ptr< HexGeom > HexGeomSharedPtr
Definition: HexGeom.h:90

◆ WritePrisms()

void Nektar::SpatialDomains::MeshGraphXml::WritePrisms ( TiXmlElement *  elmtTag,
PrismGeomMap pris 
)
protectedvirtual

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 2583 of file MeshGraphXml.cpp.

References CellMLToNektar.cellml_metadata::p.

2584 {
2585  string tag = "R";
2586 
2587  for (auto &i : pris)
2588  {
2589  stringstream s;
2590  PrismGeomSharedPtr prism = i.second;
2591  s << prism->GetFid(0) << " " << prism->GetFid(1) << " "
2592  << prism->GetFid(2) << " " << prism->GetFid(3) << " "
2593  << prism->GetFid(4) << " ";
2594  TiXmlElement *p = new TiXmlElement(tag);
2595  p->SetAttribute("ID", i.first);
2596  p->LinkEndChild(new TiXmlText(s.str()));
2597  elmtTag->LinkEndChild(p);
2598  }
2599 }
std::shared_ptr< PrismGeom > PrismGeomSharedPtr
Definition: PrismGeom.h:88

◆ WritePyrs()

void Nektar::SpatialDomains::MeshGraphXml::WritePyrs ( TiXmlElement *  elmtTag,
PyrGeomMap pyrs 
)
protectedvirtual

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 2601 of file MeshGraphXml.cpp.

References CellMLToNektar.cellml_metadata::p.

2602 {
2603  string tag = "P";
2604 
2605  for (auto &i : pyrs)
2606  {
2607  stringstream s;
2608  PyrGeomSharedPtr pyr = i.second;
2609  s << pyr->GetFid(0) << " " << pyr->GetFid(1) << " " << pyr->GetFid(2)
2610  << " " << pyr->GetFid(3) << " " << pyr->GetFid(4) << " ";
2611  TiXmlElement *p = new TiXmlElement(tag);
2612  p->SetAttribute("ID", i.first);
2613  p->LinkEndChild(new TiXmlText(s.str()));
2614  elmtTag->LinkEndChild(p);
2615  }
2616 }
std::shared_ptr< PyrGeom > PyrGeomSharedPtr
Definition: PyrGeom.h:80

◆ WriteQuads()

void Nektar::SpatialDomains::MeshGraphXml::WriteQuads ( TiXmlElement *  faceTag,
QuadGeomMap quads 
)
protectedvirtual

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 2548 of file MeshGraphXml.cpp.

2549 {
2550  string tag = "Q";
2551 
2552  for (auto &i : quads)
2553  {
2554  stringstream s;
2555  QuadGeomSharedPtr quad = i.second;
2556  s << quad->GetEid(0) << " " << quad->GetEid(1) << " " << quad->GetEid(2)
2557  << " " << quad->GetEid(3);
2558  TiXmlElement *q = new TiXmlElement(tag);
2559  q->SetAttribute("ID", i.first);
2560  q->LinkEndChild(new TiXmlText(s.str()));
2561  faceTag->LinkEndChild(q);
2562  }
2563 }
std::shared_ptr< QuadGeom > QuadGeomSharedPtr
Definition: HexGeom.h:46

◆ WriteTets()

void Nektar::SpatialDomains::MeshGraphXml::WriteTets ( TiXmlElement *  elmtTag,
TetGeomMap tets 
)
protectedvirtual

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 2618 of file MeshGraphXml.cpp.

2619 {
2620  string tag = "A";
2621 
2622  for (auto &i : tets)
2623  {
2624  stringstream s;
2625  TetGeomSharedPtr tet = i.second;
2626  s << tet->GetFid(0) << " " << tet->GetFid(1) << " " << tet->GetFid(2)
2627  << " " << tet->GetFid(3) << " ";
2628  TiXmlElement *t = new TiXmlElement(tag);
2629  t->SetAttribute("ID", i.first);
2630  t->LinkEndChild(new TiXmlText(s.str()));
2631  elmtTag->LinkEndChild(t);
2632  }
2633 }
std::shared_ptr< TetGeom > TetGeomSharedPtr
Definition: TetGeom.h:88

◆ WriteTris()

void Nektar::SpatialDomains::MeshGraphXml::WriteTris ( TiXmlElement *  faceTag,
TriGeomMap tris 
)
protectedvirtual

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 2532 of file MeshGraphXml.cpp.

2533 {
2534  string tag = "T";
2535 
2536  for (auto &i : tris)
2537  {
2538  stringstream s;
2539  TriGeomSharedPtr tri = i.second;
2540  s << tri->GetEid(0) << " " << tri->GetEid(1) << " " << tri->GetEid(2);
2541  TiXmlElement *t = new TiXmlElement(tag);
2542  t->SetAttribute("ID", i.first);
2543  t->LinkEndChild(new TiXmlText(s.str()));
2544  faceTag->LinkEndChild(t);
2545  }
2546 }
std::shared_ptr< TriGeom > TriGeomSharedPtr
Definition: TriGeom.h:58

◆ WriteVertices()

void Nektar::SpatialDomains::MeshGraphXml::WriteVertices ( TiXmlElement *  geomTag,
PointGeomMap verts 
)
protectedvirtual

Reimplemented in Nektar::SpatialDomains::MeshGraphXmlCompressed.

Definition at line 2494 of file MeshGraphXml.cpp.

2495 {
2496  TiXmlElement *vertTag = new TiXmlElement("VERTEX");
2497 
2498  for (auto &i : verts)
2499  {
2500  stringstream s;
2501  s << scientific << setprecision(8) << (*i.second)(0) << " "
2502  << (*i.second)(1) << " " << (*i.second)(2);
2503  TiXmlElement *v = new TiXmlElement("V");
2504  v->SetAttribute("ID", i.second->GetGlobalID());
2505  v->LinkEndChild(new TiXmlText(s.str()));
2506  vertTag->LinkEndChild(v);
2507  }
2508 
2509  geomTag->LinkEndChild(vertTag);
2510 }

◆ WriteXMLGeometry()

void Nektar::SpatialDomains::MeshGraphXml::WriteXMLGeometry ( std::string  outname,
std::vector< std::set< unsigned int >>  elements,
std::vector< unsigned int >  partitions 
)

Definition at line 2817 of file MeshGraphXml.cpp.

References ASSERTL0, CellMLToNektar.pycml::format, CellMLToNektar.cellml_metadata::p, and Nektar::LibUtilities::PortablePath().

Referenced by ~MeshGraphXml().

2820 {
2821  // so in theory this function is used by the mesh partitioner
2822  // giving instructions on how to write out a paritioned mesh.
2823  // the theory goes that the elements stored in the meshgraph are the
2824  // "whole" mesh so based on the information from the elmements list
2825  // we can filter the mesh entities and write some individual files
2826  // hopefully
2827 
2828  // this is xml so we are going to write a directory with lots of
2829  // xml files
2830  string dirname = outname + "_xml";
2831  boost::filesystem::path pdirname(dirname);
2832 
2833  if (!boost::filesystem::is_directory(dirname))
2834  {
2835  boost::filesystem::create_directory(dirname);
2836  }
2837 
2838  ASSERTL0(elements.size() == partitions.size(),
2839  "error in partitioned information");
2840 
2841  for (int i = 0; i < partitions.size(); i++)
2842  {
2843  TiXmlDocument doc;
2844  TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "utf-8", "");
2845  doc.LinkEndChild(decl);
2846 
2847  TiXmlElement *root = doc.FirstChildElement("NEKTAR");
2848  TiXmlElement *geomTag;
2849 
2850  // Try to find existing NEKTAR tag.
2851  if (!root)
2852  {
2853  root = new TiXmlElement("NEKTAR");
2854  doc.LinkEndChild(root);
2855 
2856  geomTag = new TiXmlElement("GEOMETRY");
2857  root->LinkEndChild(geomTag);
2858  }
2859  else
2860  {
2861  // Try to find existing GEOMETRY tag.
2862  geomTag = root->FirstChildElement("GEOMETRY");
2863 
2864  if (!geomTag)
2865  {
2866  geomTag = new TiXmlElement("GEOMETRY");
2867  root->LinkEndChild(geomTag);
2868  }
2869  }
2870 
2871  geomTag->SetAttribute("DIM", m_meshDimension);
2872  geomTag->SetAttribute("SPACE", m_spaceDimension);
2873  geomTag->SetAttribute("PARTITION", partitions[i]);
2874 
2875  // Add Mesh //
2876  // Get the elements
2877  HexGeomMap localHex;
2878  PyrGeomMap localPyr;
2879  PrismGeomMap localPrism;
2880  TetGeomMap localTet;
2881  TriGeomMap localTri;
2882  QuadGeomMap localQuad;
2883  SegGeomMap localEdge;
2884  PointGeomMap localVert;
2885  CurveMap localCurveEdge;
2886  CurveMap localCurveFace;
2887 
2888  vector<set<unsigned int>> entityIds(4);
2889  entityIds[m_meshDimension] = elements[i];
2890 
2891  switch (m_meshDimension)
2892  {
2893  case 3:
2894  {
2895  for (auto &j : entityIds[3])
2896  {
2898  if (m_hexGeoms.count(j))
2899  {
2900  g = m_hexGeoms[j];
2901  localHex[j] = m_hexGeoms[j];
2902  }
2903  else if (m_pyrGeoms.count(j))
2904  {
2905  g = m_pyrGeoms[j];
2906  localPyr[j] = m_pyrGeoms[j];
2907  }
2908  else if (m_prismGeoms.count(j))
2909  {
2910  g = m_prismGeoms[j];
2911  localPrism[j] = m_prismGeoms[j];
2912  }
2913  else if (m_tetGeoms.count(j))
2914  {
2915  g = m_tetGeoms[j];
2916  localTet[j] = m_tetGeoms[j];
2917  }
2918  else
2919  {
2920  ASSERTL0(false, "element in partition not found");
2921  }
2922 
2923  for (int k = 0; k < g->GetNumFaces(); k++)
2924  {
2925  entityIds[2].insert(g->GetFid(k));
2926  }
2927  for (int k = 0; k < g->GetNumEdges(); k++)
2928  {
2929  entityIds[1].insert(g->GetEid(k));
2930  }
2931  for (int k = 0; k < g->GetNumVerts(); k++)
2932  {
2933  entityIds[0].insert(g->GetVid(k));
2934  }
2935  }
2936  }
2937  break;
2938  case 2:
2939  {
2940  for (auto &j : entityIds[2])
2941  {
2943  if (m_triGeoms.count(j))
2944  {
2945  g = m_triGeoms[j];
2946  localTri[j] = m_triGeoms[j];
2947  }
2948  else if (m_quadGeoms.count(j))
2949  {
2950  g = m_quadGeoms[j];
2951  localQuad[j] = m_quadGeoms[j];
2952  }
2953  else
2954  {
2955  ASSERTL0(false, "element in partition not found");
2956  }
2957 
2958  for (int k = 0; k < g->GetNumEdges(); k++)
2959  {
2960  entityIds[1].insert(g->GetEid(k));
2961  }
2962  for (int k = 0; k < g->GetNumVerts(); k++)
2963  {
2964  entityIds[0].insert(g->GetVid(k));
2965  }
2966  }
2967  }
2968  break;
2969  case 1:
2970  {
2971  for (auto &j : entityIds[1])
2972  {
2974  if (m_segGeoms.count(j))
2975  {
2976  g = m_segGeoms[j];
2977  localEdge[j] = m_segGeoms[j];
2978  }
2979  else
2980  {
2981  ASSERTL0(false, "element in partition not found");
2982  }
2983 
2984  for (int k = 0; k < g->GetNumVerts(); k++)
2985  {
2986  entityIds[0].insert(g->GetVid(k));
2987  }
2988  }
2989  }
2990  }
2991 
2992  if (m_meshDimension > 2)
2993  {
2994  for (auto &j : entityIds[2])
2995  {
2996  if (m_triGeoms.count(j))
2997  {
2998  localTri[j] = m_triGeoms[j];
2999  }
3000  else if (m_quadGeoms.count(j))
3001  {
3002  localQuad[j] = m_quadGeoms[j];
3003  }
3004  else
3005  {
3006  ASSERTL0(false, "face not found");
3007  }
3008  }
3009  }
3010 
3011  if (m_meshDimension > 1)
3012  {
3013  for (auto &j : entityIds[1])
3014  {
3015  if (m_segGeoms.count(j))
3016  {
3017  localEdge[j] = m_segGeoms[j];
3018  }
3019  else
3020  {
3021  ASSERTL0(false, "edge not found");
3022  }
3023  }
3024  }
3025 
3026  for (auto &j : entityIds[0])
3027  {
3028  if (m_vertSet.count(j))
3029  {
3030  localVert[j] = m_vertSet[j];
3031  }
3032  else
3033  {
3034  ASSERTL0(false, "vert not found");
3035  }
3036  }
3037 
3038  WriteVertices(geomTag, localVert);
3039  WriteEdges(geomTag, localEdge);
3040  if (m_meshDimension > 1)
3041  {
3042  TiXmlElement *faceTag =
3043  new TiXmlElement(m_meshDimension == 2 ? "ELEMENT" : "FACE");
3044 
3045  WriteTris(faceTag, localTri);
3046  WriteQuads(faceTag, localQuad);
3047  geomTag->LinkEndChild(faceTag);
3048  }
3049  if (m_meshDimension > 2)
3050  {
3051  TiXmlElement *elmtTag = new TiXmlElement("ELEMENT");
3052 
3053  WriteHexs(elmtTag, localHex);
3054  WritePyrs(elmtTag, localPyr);
3055  WritePrisms(elmtTag, localPrism);
3056  WriteTets(elmtTag, localTet);
3057 
3058  geomTag->LinkEndChild(elmtTag);
3059  }
3060 
3061  for (auto &j : localTri)
3062  {
3063  if (m_curvedFaces.count(j.first))
3064  {
3065  localCurveFace[j.first] = m_curvedFaces[j.first];
3066  }
3067  }
3068  for (auto &j : localQuad)
3069  {
3070  if (m_curvedFaces.count(j.first))
3071  {
3072  localCurveFace[j.first] = m_curvedFaces[j.first];
3073  }
3074  }
3075  for (auto &j : localEdge)
3076  {
3077  if (m_curvedEdges.count(j.first))
3078  {
3079  localCurveEdge[j.first] = m_curvedEdges[j.first];
3080  }
3081  }
3082 
3083  WriteCurves(geomTag, localCurveEdge, localCurveFace);
3084 
3085  CompositeMap localComp;
3086 
3087  for (auto &j : m_meshComposites)
3088  {
3089  CompositeSharedPtr comp = CompositeSharedPtr(new Composite);
3090  int dim = j.second->m_geomVec[0]->GetShapeDim();
3091 
3092  for (int k = 0; k < j.second->m_geomVec.size(); k++)
3093  {
3094  if (entityIds[dim].count(j.second->m_geomVec[k]->GetGlobalID()))
3095  {
3096  comp->m_geomVec.push_back(j.second->m_geomVec[k]);
3097  }
3098  }
3099 
3100  if (comp->m_geomVec.size())
3101  {
3102  localComp[j.first] = comp;
3103  }
3104  }
3105 
3106  WriteComposites(geomTag, localComp);
3107 
3108  vector<CompositeMap> domain;
3109  CompositeMap domMap;
3110  for (auto &j : localComp)
3111  {
3112  if (j.second->m_geomVec[0]->GetShapeDim() == m_meshDimension)
3113  {
3114  domMap[j.first] = j.second;
3115  }
3116  }
3117  domain.push_back(domMap);
3118 
3119  WriteDomain(geomTag, domain);
3120 
3121  if (m_session->DefinesElement("NEKTAR/CONDITIONS"))
3122  {
3123  std::set<int> vBndRegionIdList;
3124  TiXmlElement *vConditions =
3125  new TiXmlElement(*m_session->GetElement("Nektar/Conditions"));
3126  TiXmlElement *vBndRegions =
3127  vConditions->FirstChildElement("BOUNDARYREGIONS");
3128  TiXmlElement *vBndConditions =
3129  vConditions->FirstChildElement("BOUNDARYCONDITIONS");
3130  TiXmlElement *vItem;
3131 
3132  if (vBndRegions)
3133  {
3134  TiXmlElement *vNewBndRegions =
3135  new TiXmlElement("BOUNDARYREGIONS");
3136  vItem = vBndRegions->FirstChildElement();
3137  while (vItem)
3138  {
3139  std::string vSeqStr =
3140  vItem->FirstChild()->ToText()->Value();
3141  std::string::size_type indxBeg =
3142  vSeqStr.find_first_of('[') + 1;
3143  std::string::size_type indxEnd =
3144  vSeqStr.find_last_of(']') - 1;
3145  vSeqStr = vSeqStr.substr(indxBeg, indxEnd - indxBeg + 1);
3146  std::vector<unsigned int> vSeq;
3147  ParseUtils::GenerateSeqVector(vSeqStr.c_str(), vSeq);
3148 
3149  vector<unsigned int> idxList;
3150 
3151  for (unsigned int i = 0; i < vSeq.size(); ++i)
3152  {
3153  if (localComp.find(vSeq[i]) != localComp.end())
3154  {
3155  idxList.push_back(vSeq[i]);
3156  }
3157  }
3158  int p = atoi(vItem->Attribute("ID"));
3159 
3160  std::string vListStr =
3162 
3163  if (vListStr.length() == 0)
3164  {
3165  TiXmlElement *tmp = vItem;
3166  vItem = vItem->NextSiblingElement();
3167  vBndRegions->RemoveChild(tmp);
3168  }
3169  else
3170  {
3171  vListStr = "C[" + vListStr + "]";
3172  TiXmlText *vList = new TiXmlText(vListStr);
3173  TiXmlElement *vNewElement = new TiXmlElement("B");
3174  vNewElement->SetAttribute("ID", p);
3175  vNewElement->LinkEndChild(vList);
3176  vNewBndRegions->LinkEndChild(vNewElement);
3177  vBndRegionIdList.insert(p);
3178  vItem = vItem->NextSiblingElement();
3179  }
3180 
3181  // store original bnd region order
3182  m_bndRegOrder[p] = vSeq;
3183  }
3184  vConditions->ReplaceChild(vBndRegions, *vNewBndRegions);
3185  }
3186 
3187  if (vBndConditions)
3188  {
3189  vItem = vBndConditions->FirstChildElement();
3190  while (vItem)
3191  {
3192  std::set<int>::iterator x;
3193  if ((x = vBndRegionIdList.find(atoi(vItem->Attribute(
3194  "REF")))) != vBndRegionIdList.end())
3195  {
3196  vItem->SetAttribute("REF", *x);
3197  vItem = vItem->NextSiblingElement();
3198  }
3199  else
3200  {
3201  TiXmlElement *tmp = vItem;
3202  vItem = vItem->NextSiblingElement();
3203  vBndConditions->RemoveChild(tmp);
3204  }
3205  }
3206  }
3207  root->LinkEndChild(vConditions);
3208  }
3209 
3210  // Distribute other sections of the XML to each process as is.
3211  TiXmlElement *vSrc =
3212  m_session->GetElement("Nektar")->FirstChildElement();
3213  while (vSrc)
3214  {
3215  std::string vName = boost::to_upper_copy(vSrc->ValueStr());
3216  if (vName != "GEOMETRY" && vName != "CONDITIONS")
3217  {
3218  root->LinkEndChild(new TiXmlElement(*vSrc));
3219  }
3220  vSrc = vSrc->NextSiblingElement();
3221  }
3222 
3223  // Save Mesh
3224 
3225  boost::format pad("P%1$07d.xml");
3226  pad % partitions[i];
3227  boost::filesystem::path pFilename(pad.str());
3228 
3229  boost::filesystem::path fullpath = pdirname / pFilename;
3230  doc.SaveFile(LibUtilities::PortablePath(fullpath));
3231  }
3232 }
void WriteComposites(TiXmlElement *geomTag, CompositeMap &comps)
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
virtual void WriteHexs(TiXmlElement *elmtTag, HexGeomMap &hexs)
LibUtilities::SessionReaderSharedPtr m_session
Definition: MeshGraph.h:435
std::unordered_map< int, CurveSharedPtr > CurveMap
Definition: Curve.hpp:62
virtual void WriteEdges(TiXmlElement *geomTag, SegGeomMap &edges)
std::map< int, CompositeSharedPtr > CompositeMap
Definition: MeshGraph.h:137
std::map< int, PrismGeomSharedPtr > PrismGeomMap
Definition: PrismGeom.h:89
std::shared_ptr< Composite > CompositeSharedPtr
Definition: MeshGraph.h:136
std::map< int, PyrGeomSharedPtr > PyrGeomMap
Definition: PyrGeom.h:81
virtual void WriteTris(TiXmlElement *faceTag, TriGeomMap &tris)
std::map< int, TetGeomSharedPtr > TetGeomMap
Definition: TetGeom.h:90
std::map< int, TriGeomSharedPtr > TriGeomMap
Definition: TriGeom.h:59
virtual void WritePyrs(TiXmlElement *elmtTag, PyrGeomMap &pyrs)
virtual void WriteTets(TiXmlElement *elmtTag, TetGeomMap &tets)
std::map< int, SegGeomSharedPtr > SegGeomMap
Definition: SegGeom.h:52
std::shared_ptr< Geometry > GeometrySharedPtr
Definition: Geometry.h:53
virtual void WriteVertices(TiXmlElement *geomTag, PointGeomMap &verts)
std::string PortablePath(const boost::filesystem::path &path)
create portable path on different platforms for boost::filesystem path
Definition: FileSystem.cpp:41
void WriteDomain(TiXmlElement *geomTag, std::vector< CompositeMap > &domain)
virtual void WriteQuads(TiXmlElement *faceTag, QuadGeomMap &quads)
static std::string GenerateSeqString(const std::vector< T > &v)
Generate a compressed comma-separated string representation of a vector of unsigned integers...
Definition: ParseUtils.h:71
virtual void WritePrisms(TiXmlElement *elmtTag, PrismGeomMap &pris)
BndRegionOrdering m_bndRegOrder
Definition: MeshGraph.h:469
std::map< int, QuadGeomSharedPtr > QuadGeomMap
Definition: QuadGeom.h:54
std::map< int, PointGeomSharedPtr > PointGeomMap
Definition: PointGeom.h:54
std::map< int, HexGeomSharedPtr > HexGeomMap
Definition: HexGeom.h:91
virtual void WriteCurves(TiXmlElement *geomTag, CurveMap &edges, CurveMap &faces)
static bool GenerateSeqVector(const std::string &str, std::vector< unsigned int > &out)
Takes a comma-separated compressed string and converts it to entries in a vector. ...
Definition: ParseUtils.cpp:108

Member Data Documentation

◆ className

std::string Nektar::SpatialDomains::MeshGraphXml::className
static
Initial value:

Definition at line 74 of file MeshGraphXml.h.