Commit cc8fde31 authored by Michael Turner's avatar Michael Turner
Browse files

clean up element

parent 1ad9db91
......@@ -52,6 +52,7 @@ SET(NEKMESHUTILS_HEADERS
MeshElements/Prism.h
MeshElements/Hexahedron.h
MeshElements/HOAlignment.h
MeshElements/ElementConfig.h
)
IF(NEKTAR_USE_MESHGEN)
......
......@@ -64,18 +64,6 @@ Element::Element(ElmtConfig pConf, unsigned int pNumNodes,
}
}
/**
* @brief Replace a vertex in the element.
*
* When a vertex is replaced, the element edges and faces are also
* searched and the corresponding edge/face nodes are updated to
* maintain consistency.
*
* @param p Index of the vertex to replace.
* @param pNew New vertex.
* @param descend If true, we loop over edges and faces and replace the
* corresponding vertices with @p pNew.
*/
void Element::SetVertex(unsigned int p, NodeSharedPtr pNew, bool descend)
{
NodeSharedPtr vOld = m_vertex[p];
......@@ -121,17 +109,6 @@ void Element::SetVertex(unsigned int p, NodeSharedPtr pNew, bool descend)
}
}
/**
* @brief Replace an edge in the element.
*
* When an edge is replaced, the element faces are also searched and
* the corresponding face edges are updated to maintain consistency.
*
* @param p Index of the edge to replace.
* @param pNew New edge.
* @param descend If true, we loop over faces and replace the corresponding
* face edge with @p pNew.
*/
void Element::SetEdge(unsigned int p, EdgeSharedPtr pNew, bool descend)
{
EdgeSharedPtr vOld = m_edge[p];
......@@ -154,22 +131,11 @@ void Element::SetEdge(unsigned int p, EdgeSharedPtr pNew, bool descend)
}
}
/**
* @brief Replace a face in the element.
*
* When a face is replaced, no other consistency checks are required.
*
* @param p Index of the face to replace.
* @param pNew New face.
*/
void Element::SetFace(unsigned int p, FaceSharedPtr pNew)
{
m_face[p] = pNew;
}
/**
* @brief Obtain the order of an element by looking at edges.
*/
int Element::GetMaxOrder()
{
int i, ret = 1;
......@@ -185,5 +151,85 @@ int Element::GetMaxOrder()
return ret;
}
unsigned int Element::GetNodeCount()
{
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
{
for (int i = 0; i < m_face.size(); ++i)
{
n += m_face[i]->GetNodeCount();
}
for (int i = 0; i < m_edge.size(); ++i)
{
n -= m_edge[i]->GetNodeCount();
}
n += m_vertex.size();
std::cerr << "Not supported." << std::endl;
exit(1);
}
return n;
}
string Element::GetXmlString()
{
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();
}
string Element::GetXmlCurveString()
{
// Temporary node list for reordering
std::vector<NodeSharedPtr> nodeList;
GetCurvedNodes(nodeList);
// Finally generate the XML string corresponding to our new
// node reordering.
std::stringstream s;
std::string str;
for (int k = 0; k < nodeList.size(); ++k)
{
s << std::scientific << std::setprecision(8) << " "
<< nodeList[k]->m_x << " " << nodeList[k]->m_y << " "
<< nodeList[k]->m_z << " ";
}
return s.str();
}
}
}
......@@ -42,67 +42,13 @@
#include <NekMeshUtils/NekMeshUtilsDeclspec.h>
#include <NekMeshUtils/MeshElements/Face.h>
#include <NekMeshUtils/MeshElements/ElementConfig.h>
namespace Nektar
{
namespace NekMeshUtils
{
/**
* @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;
};
NEKMESHUTILS_EXPORT bool operator==(ElmtConfig const &c1, ElmtConfig const &c2);
/**
* @brief Base class for element definitions.
*
......@@ -199,37 +145,7 @@ public:
}
/// Returns the total number of nodes (vertices, edge nodes and
/// face nodes and volume nodes).
NEKMESHUTILS_EXPORT 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
{
for (int i = 0; i < m_face.size(); ++i)
{
n += m_face[i]->GetNodeCount();
}
for (int i = 0; i < m_edge.size(); ++i)
{
n -= m_edge[i]->GetNodeCount();
}
n += m_vertex.size();
std::cerr << "Not supported." << std::endl;
exit(1);
}
return n;
}
NEKMESHUTILS_EXPORT unsigned int GetNodeCount();
/// Access the list of tags associated with this element.
NEKMESHUTILS_EXPORT std::vector<int> GetTagList() const
{
......@@ -255,13 +171,41 @@ public:
{
m_id = p;
}
/// Replace a vertex with another vertex object.
/**
* @brief Replace a vertex in the element.
*
* When a vertex is replaced, the element edges and faces are also
* searched and the corresponding edge/face nodes are updated to
* maintain consistency.
*
* @param p Index of the vertex to replace.
* @param pNew New vertex.
* @param descend If true, we loop over edges and faces and replace the
* corresponding vertices with @p pNew.
*/
NEKMESHUTILS_EXPORT void SetVertex(
unsigned int p, NodeSharedPtr pNew, bool descend = true);
/// Replace an edge with another edge object.
/**
* @brief Replace an edge in the element.
*
* When an edge is replaced, the element faces are also searched and
* the corresponding face edges are updated to maintain consistency.
*
* @param p Index of the edge to replace.
* @param pNew New edge.
* @param descend If true, we loop over faces and replace the corresponding
* face edge with @p pNew.
*/
NEKMESHUTILS_EXPORT void SetEdge(
unsigned int p, EdgeSharedPtr pNew, bool descend = true);
/// Replace a face with another face object.
/**
* @brief Replace a face in the element.
*
* When a face is replaced, no other consistency checks are required.
*
* @param p Index of the face to replace.
* @param pNew New face.
*/
NEKMESHUTILS_EXPORT void SetFace(unsigned int p, FaceSharedPtr pNew);
/// Set a correspondence between this element and an edge
/// (2D boundary element).
......@@ -310,154 +254,18 @@ public:
m_taglist = tags;
}
/// Generate a list of vertices (1D), edges (2D), or faces (3D).
NEKMESHUTILS_EXPORT 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();
}
NEKMESHUTILS_EXPORT virtual std::string GetXmlString();
/// get list of volume interior nodes
NEKMESHUTILS_EXPORT virtual void GetCurvedNodes(
std::vector<NodeSharedPtr> &nodeList) const
{
ASSERTL0(false,
"This function should be implemented at a shape level.");
/*std::cerr << "WARNING: Unsupported curvature for a " << m_vertex.size()
<< "-vertex element is not yet implemented." << std::endl;
// 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));
}
}
// Copy volume nodes.
std::copy(m_volumeNodes.begin(),
m_volumeNodes.end(),
nodeList.begin() + 3 * (n - 1));
}
// Quad
else if (m_dim == 2 && m_vertex.size() == 4)
{
int n = m_edge[0]->GetNodeCount();
nodeList.resize(n * n);
// Write vertices
nodeList[0] = m_vertex[0];
nodeList[n - 1] = m_vertex[1];
nodeList[n * n - 1] = m_vertex[2];
nodeList[n * (n - 1)] = m_vertex[3];
// Write edge-interior
int skips[4][2] = {
{0, 1}, {n - 1, n}, {n * n - 1, -1}, {n * (n - 1), -n}};
for (int i = 0; i < 4; ++i)
{
bool reverseEdge = m_edge[i]->m_n1 == m_vertex[i];
if (!reverseEdge)
{
for (int j = 1; j < n - 1; ++j)
{
nodeList[skips[i][0] + j * skips[i][1]] =
m_edge[i]->m_edgeNodes[n - 2 - j];
}
}
else
{
for (int j = 1; j < n - 1; ++j)
{
nodeList[skips[i][0] + j * skips[i][1]] =
m_edge[i]->m_edgeNodes[j - 1];
}
}
}
// Write interior
for (int i = 1; i < n - 1; ++i)
{
for (int j = 1; j < n - 1; ++j)
{
nodeList[i * n + j] =
m_volumeNodes[(i - 1) * (n - 2) + (j - 1)];
}
}
}
else
{
std::cerr << "GetXmlCurveString for a " << m_vertex.size()
<< "-vertex element is not yet implemented."
<< std::endl;
}*/
}
/// Generates a string listing the coordinates of all nodes
/// associated with this element.
NEKMESHUTILS_EXPORT std::string GetXmlCurveString() const
{
// Temporary node list for reordering
std::vector<NodeSharedPtr> nodeList;
GetCurvedNodes(nodeList);
// Finally generate the XML string corresponding to our new
// node reordering.
std::stringstream s;
std::string str;
for (int k = 0; k < nodeList.size(); ++k)
{
s << std::scientific << std::setprecision(8) << " "
<< nodeList[k]->m_x << " " << nodeList[k]->m_y << " "
<< nodeList[k]->m_z << " ";
}
return s.str();
}
NEKMESHUTILS_EXPORT std::string GetXmlCurveString();
/// Generate a Nektar++ geometry object for this element.
NEKMESHUTILS_EXPORT virtual SpatialDomains::GeometrySharedPtr GetGeom(
int coordDim)
......@@ -467,6 +275,9 @@ public:
return boost::shared_ptr<SpatialDomains::Geometry>();
}
/**
* @brief Obtain the order of an element by looking at edges.
*/
NEKMESHUTILS_EXPORT int GetMaxOrder();
/**
......
////////////////////////////////////////////////////////////////////////////////
//
// File: ElementConfig.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 elementconfig.
//
////////////////////////////////////////////////////////////////////////////////
#ifndef NEKMESHUTILS_MESHELEMENTS_ELEMENTCONFIG
#define NEKMESHUTILS_MESHELEMENTS_ELEMENTCONFIG
namespace Nektar
{
namespace NekMeshUtils
{
/**
* @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;
};
NEKMESHUTILS_EXPORT bool operator==(ElmtConfig const &c1, ElmtConfig const &c2);
}
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment