Commit c3aa096c authored by Michael Turner's avatar Michael Turner

split mesh elements header file

parent 60d58101
......@@ -18,6 +18,20 @@ ENDIF()
SET(MESHUTILS_HEADERS
MeshElements/MeshElements.h
MeshElements/Node.h
MeshElements/Edge.h
MeshElements/Face.h
MeshElements/Element.h
MeshElements/Composite.h
MeshElements/Mesh.h
MeshElements/Point.h
MeshElements/Line.h
MeshElements/Triangle.h
MeshElements/Quadrilateral.h
MeshElements/Tetrahedron.h
MeshElements/Pyramid.h
MeshElements/Prism.h
MeshElements/Hexahedron.h
)
IF(NEKTAR_USE_MESH)
SET(MESHUTILS_HEADERS ${MESHUTILS_HEADERS}
......
////////////////////////////////////////////////////////////////////////////////
//
// File: Face.h
//
// For more information, please see: http://www.nektar.info/
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Mesh manipulation objects.
//
////////////////////////////////////////////////////////////////////////////////
#ifndef MESHUTILS_MESHELEMENTS_COMPOSITE
#define MESHUTILS_MESHELEMENTS_COMPOSITE
namespace Nektar
{
namespace Utilities
{
/**
* @brief A composite is a collection of elements.
*
* All elements should be of the same type, i.e. have the same tag.
*/
class Composite {
public:
Composite() : m_reorder(true) {}
/// Generate the list of IDs of elements within this composite.
std::string GetXmlString(bool doSort=true);
/// ID of composite.
unsigned int m_id;
/// Element type tag.
std::string m_tag;
/// boundary label
std::string m_label;
/// Determines whether items can be reordered.
bool m_reorder;
/// List of elements in this composite.
std::vector<ElementSharedPtr> m_items;
};
/// Shared pointer to a composite.
typedef boost::shared_ptr<Composite> CompositeSharedPtr;
/// Container of composites; key is the composite id, value is the
/// composite.
typedef std::map<unsigned int, CompositeSharedPtr> CompositeMap;
}
}
#endif
////////////////////////////////////////////////////////////////////////////////
//
// File: Edge.h
//
// For more information, please see: http://www.nektar.info/
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Mesh manipulation objects.
//
////////////////////////////////////////////////////////////////////////////////
#ifndef MESHUTILS_MESHELEMENTS_EDGE
#define MESHUTILS_MESHELEMENTS_EDGE
namespace Nektar
{
namespace Utilities
{
/**
* @brief Represents an edge which joins two points.
*
* An edge is defined by two nodes (vertices) and, for high-order edges,
* a set of control nodes defining the shape of the edge.
*/
class Edge {
public:
/// Creates a new edge.
Edge(NodeSharedPtr pVertex1, NodeSharedPtr pVertex2,
std::vector<NodeSharedPtr> pEdgeNodes,
LibUtilities::PointsType pCurveType)
: m_n1(pVertex1), m_n2(pVertex2), m_edgeNodes(pEdgeNodes),
m_curveType(pCurveType), m_geom() {}
/// Copies an existing edge.
Edge(const Edge& pSrc)
: m_n1(pSrc.m_n1), m_n2(pSrc.m_n2), m_edgeNodes(pSrc.m_edgeNodes),
m_curveType(pSrc.m_curveType), m_geom(pSrc.m_geom) {}
~Edge() {}
/// Returns the total number of nodes defining the edge.
unsigned int GetNodeCount() const
{
return m_edgeNodes.size() + 2;
}
/// Creates a Nektar++ string listing the coordinates of all the
/// nodes.
std::string GetXmlCurveString() const
{
std::stringstream s;
std::string str;
s << std::scientific << std::setprecision(8) << " "
<< m_n1->m_x << " " << m_n1->m_y << " " << m_n1->m_z << " ";
for (int k = 0; k < m_edgeNodes.size(); ++k) {
s << std::scientific << std::setprecision(8) << " "
<< m_edgeNodes[k]->m_x << " " << m_edgeNodes[k]->m_y
<< " " << m_edgeNodes[k]->m_z << " ";
}
s << std::scientific << std::setprecision(8) << " "
<< m_n2->m_x << " " << m_n2->m_y << " " << m_n2->m_z;
return s.str();
}
/// Generate a SpatialDomains::SegGeom object for this edge.
SpatialDomains::SegGeomSharedPtr GetGeom(int coordDim)
{
// Create edge vertices.
SpatialDomains::PointGeomSharedPtr p[2];
SpatialDomains::SegGeomSharedPtr ret;
p[0] = m_n1->GetGeom(coordDim);
p[1] = m_n2->GetGeom(coordDim);
// Create a curve if high-order information exists.
if (m_edgeNodes.size() > 0)
{
SpatialDomains::CurveSharedPtr c =
MemoryManager<SpatialDomains::Curve>::
AllocateSharedPtr(m_id, m_curveType);
c->m_points.push_back(p[0]);
for (int i = 0; i < m_edgeNodes.size(); ++i)
{
c->m_points.push_back(m_edgeNodes[i]->GetGeom(coordDim));
}
c->m_points.push_back(p[1]);
ret = MemoryManager<SpatialDomains::SegGeom>::
AllocateSharedPtr(m_id, coordDim, p, c);
}
else
{
ret = MemoryManager<SpatialDomains::SegGeom>::
AllocateSharedPtr(m_id, coordDim, p);
}
return ret;
}
/// ID of edge.
unsigned int m_id;
/// First vertex node.
NodeSharedPtr m_n1;
/// Second vertex node.
NodeSharedPtr m_n2;
/// List of control nodes between the first and second vertices.
std::vector<NodeSharedPtr> m_edgeNodes;
/// Distributions of points along edge.
LibUtilities::PointsType m_curveType;
/// Element(s) which are linked to this edge.
vector<pair<ElementSharedPtr, int> > m_elLink;
private:
SpatialDomains::SegGeomSharedPtr m_geom;
};
/// Shared pointer to an edge.
typedef boost::shared_ptr<Edge> EdgeSharedPtr;
bool operator==(EdgeSharedPtr const &p1, EdgeSharedPtr const &p2);
bool operator< (EdgeSharedPtr const &p1, EdgeSharedPtr const &p2);
/**
* @brief Defines a hash function for edges.
*
* The hash of an edge is defined using the IDs of the two nodes which
* define it. First the minimum ID is hashed, then the maximum
* ID, which takes the two possible orientations into account.
*/
struct EdgeHash : std::unary_function<EdgeSharedPtr, std::size_t>
{
std::size_t operator()(EdgeSharedPtr const& p) const
{
std::size_t seed = 0;
unsigned int id1 = p->m_n1->m_id;
unsigned int id2 = p->m_n2->m_id;
boost::hash_combine(seed, id1 < id2 ? id1 : id2);
boost::hash_combine(seed, id2 < id1 ? id1 : id2);
return seed;
}
};
typedef boost::unordered_set<EdgeSharedPtr, EdgeHash> EdgeSet;
}
}
#endif
////////////////////////////////////////////////////////////////////////////////
//
// File: Element.h
//
// For more information, please see: http://www.nektar.info/
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Mesh manipulation objects.
//
////////////////////////////////////////////////////////////////////////////////
#ifndef MESHUTILS_MESHELEMENTS_ELEMENT
#define MESHUTILS_MESHELEMENTS_ELEMENT
namespace Nektar
{
namespace Utilities
{
/**
* @brief Basic information about an element.
*
* ElmtConfig contains four member variables which denote the
* properties of an element when it is created.
*/
struct ElmtConfig
{
ElmtConfig(LibUtilities::ShapeType pE,
unsigned int pOrder,
bool pFn,
bool pVn,
bool pReorient = true,
LibUtilities::PointsType pECt
= LibUtilities::ePolyEvenlySpaced,
LibUtilities::PointsType pFCt
= LibUtilities::ePolyEvenlySpaced)
: m_e (pE),
m_faceNodes (pFn),
m_volumeNodes (pVn),
m_order (pOrder),
m_reorient (pReorient),
m_edgeCurveType(pECt),
m_faceCurveType(pFCt)
{
}
ElmtConfig(ElmtConfig const &p) :
m_e (p.m_e),
m_faceNodes (p.m_faceNodes),
m_volumeNodes (p.m_volumeNodes),
m_order (p.m_order),
m_reorient (p.m_reorient),
m_edgeCurveType(p.m_edgeCurveType),
m_faceCurveType(p.m_faceCurveType)
{
}
ElmtConfig() {}
/// Element type (e.g. triangle, quad, etc).
LibUtilities::ShapeType m_e;
/// Denotes whether the element contains face nodes. For 2D
/// elements, if this is true then the element contains interior
/// nodes.
bool m_faceNodes;
/// Denotes whether the element contains volume (i.e. interior)
/// nodes. These are not supported by either the mesh converter or
/// Nektar++ but are included for completeness and are required
/// for some output modules (e.g. Gmsh).
bool m_volumeNodes;
/// Order of the element.
unsigned int m_order;
/// Denotes whether the element needs to be re-orientated for a
/// spectral element framework.
bool m_reorient;
/// Distribution of points in edges.
LibUtilities::PointsType m_edgeCurveType;
/// Distribution of points in faces.
LibUtilities::PointsType m_faceCurveType;
};
/**
* @brief Base class for element definitions.
*
* An element is defined by a list of vertices, edges and faces
* (depending on the dimension of the problem). This base class
* provides the underlying structure.
*/
class Element {
public:
Element(ElmtConfig pConf,
unsigned int pNumNodes,
unsigned int pGotNodes);
/// Returns the ID of the element (or associated edge or face for
/// boundary elements).
unsigned int GetId() const {
if (m_faceLink.get() != 0) return m_faceLink->m_id;
if (m_edgeLink.get() != 0) return m_edgeLink->m_id;
return m_id;
}
/// returns id of the Tri which this elemnt was created from in
/// mesh utils, only applys to surface elements
int GetTriID() const {
return m_meshtriID;
}
void SetTriID(int i) {
m_meshtriID = i;
}
/// Returns the expansion dimension of the element.
unsigned int GetDim() const {
return m_dim;
}
/// Returns the configuration of the element.
ElmtConfig GetConf() const {
return m_conf;
}
/// Returns the tag which defines the element shape.
std::string GetTag() const {
if (m_faceLink.get() != 0) return "F";
if (m_edgeLink.get() != 0) return "E";
return m_tag;
}
/// Access a vertex node.
NodeSharedPtr GetVertex(unsigned int i) const {
return m_vertex[i];
}
/// Access an edge.
EdgeSharedPtr GetEdge(unsigned int i) const {
return m_edge[i];
}
/// Access a face.
FaceSharedPtr GetFace(unsigned int i) const {
return m_face[i];
}
/// Access the list of vertex nodes.
std::vector<NodeSharedPtr> GetVertexList() const {
return m_vertex;
}
/// Access the list of edges.
std::vector<EdgeSharedPtr> GetEdgeList() const {
return m_edge;
}
/// Access the list of faces.
std::vector<FaceSharedPtr> GetFaceList() const {
return m_face;
}
/// Access the list of volume nodes.
std::vector<NodeSharedPtr> GetVolumeNodes() const {
return m_volumeNodes;
}
void SetVolumeNodes(std::vector<NodeSharedPtr> &nodes) {
m_volumeNodes = nodes;
}
LibUtilities::PointsType GetCurveType() const {
return m_curveType;
}
void SetCurveType(LibUtilities::PointsType cT) {
m_curveType = cT;
}
/// Returns the total number of nodes (vertices, edge nodes and
/// face nodes and volume nodes).
unsigned int GetNodeCount() const
{
unsigned int n = m_volumeNodes.size();
if (m_dim == 1)
{
n += 2;
}
else if (m_dim == 2)
{
for (int i = 0; i < m_edge.size(); ++i)
{
n += m_edge[i]->GetNodeCount();
}
n -= m_vertex.size();
}
else
{
cerr << "Not supported." << endl;
exit(1);
}
return n;
}
/// Access the list of tags associated with this element.
std::vector<int> GetTagList() const {
return m_taglist;
}
/// Returns the number of vertices.
unsigned int GetVertexCount() const {
return m_vertex.size();
}
/// Returns the number of edges.
unsigned int GetEdgeCount() const {
return m_edge.size();
}
/// Returns the number of faces.
unsigned int GetFaceCount() const {
return m_face.size();
}
/// Change the ID of the element.
void SetId(unsigned int p) {
m_id = p;
}
/// Replace a vertex with another vertex object.
void SetVertex(unsigned int p, NodeSharedPtr pNew);
/// Replace an edge with another edge object.
void SetEdge(unsigned int p, EdgeSharedPtr pNew);
/// Replace a face with another face object.
void SetFace(unsigned int p, FaceSharedPtr pNew);
/// Set a correspondence between this element and an edge
/// (2D boundary element).
void SetEdgeLink(EdgeSharedPtr pLink) {
m_edgeLink = pLink;
}
/// Get correspondence between this element and an edge.
EdgeSharedPtr GetEdgeLink() {
return m_edgeLink;
}
/// Set a correspondence between this element and a face
/// (3D boundary element).
void SetFaceLink(FaceSharedPtr pLink) {
m_faceLink = pLink;
}
/// Get correspondence between this element and a face.
FaceSharedPtr GetFaceLink() {
return m_faceLink;
}
/// Set a correspondence between edge or face i and its
/// representative boundary element m->element[expDim-1][j].
void SetBoundaryLink(int i, int j) {
m_boundaryLinks[i] = j;
}
/// Get the location of the boundary face/edge i for this element.
int GetBoundaryLink(int i) {
std::map<int,int>::iterator it = m_boundaryLinks.find(i);
if (it == m_boundaryLinks.end())
{
return -1;
}
else
{
return it->second;
}
}
/// Set the list of tags associated with this element.
void SetTagList(const std::vector<int> &tags)
{
m_taglist = tags;
}
/// Generate a list of vertices (1D), edges (2D), or faces (3D).
virtual std::string GetXmlString() const
{
std::stringstream s;
switch (m_dim)
{
case 1:
for(int j=0; j< m_vertex.size(); ++j)
{
s << std::setw(5) << m_vertex[j]->m_id << " ";
}
break;
case 2:
for(int j=0; j< m_edge.size(); ++j)
{
s << std::setw(5) << m_edge[j]->m_id << " ";
}
break;
case 3:
for(int j=0; j< m_face.size(); ++j)
{
s << std::setw(5) << m_face[j]->m_id << " ";
}
break;
}
return s.str();
}
/// Generates a string listing the coordinates of all nodes
/// associated with this element.
std::string GetXmlCurveString() const
{
// Temporary node list for reordering
std::vector<NodeSharedPtr> nodeList;
// Node orderings are different for different elements.
// Triangle
if (m_vertex.size() == 2)
{
nodeList.push_back(m_vertex[0]);
for (int i = 0; i < m_volumeNodes.size(); ++i)
{
nodeList.push_back(m_volumeNodes[i]);
}
nodeList.push_back(m_vertex[1]);
}
else if (m_vertex.size() == 3)
{
int n = m_edge[0]->GetNodeCount();
nodeList.resize(n*(n+1)/2);
// Populate nodelist
std::copy(m_vertex.begin(), m_vertex.end(), nodeList.begin());
for (int i = 0; i < 3; ++i)
{
std::copy(m_edge[i]->m_edgeNodes.begin(),
m_edge[i]->m_edgeNodes.end(),
nodeList.begin() + 3 + i*(n-2));
if (m_edge[i]->m_n1 != m_vertex[i])
{
// If edge orientation is reversed relative to node
// ordering, we need to reverse order of nodes.
std::reverse(nodeList.begin() + 3 + i*(n-2),
nodeList.begin() + 3 + (i+1)*(n-2));